gohugoio/hugo · error
id must not contain forward slashes
Error message
id must not contain forward slashes
What it means
Returned by ValidateBatchID in Hugo's esbuild JS batching support (internal/js/esbuild/batch.go:162). Batch script/group/instance IDs become part of generated file paths and import identifiers, so only top-level batch IDs may contain '/'; nested IDs (groups, scripts within a group) must be flat single-segment names. A separate check also rejects backslashes in all IDs.
Source
Thrown at internal/js/esbuild/batch.go:163
o.compiledPrev = o.compiled
o.compiled, o.compileErr = o.compiled.compileOptions(m, o.defaults)
o.checkCompileErr()
return ""
}
// ValidateBatchID validates the given ID according to some very
func ValidateBatchID(id string, isTopLevel bool) error {
if id == "" {
return fmt.Errorf("id must be set")
}
// No Windows slashes.
if strings.Contains(id, "\\") {
return fmt.Errorf("id must not contain backslashes")
}
// Allow forward slashes in top level IDs only.
if !isTopLevel && strings.Contains(id, "/") {
return fmt.Errorf("id must not contain forward slashes")
}
return nil
}
func newIsBuiltOrTouched() isBuiltOrTouched {
return isBuiltOrTouched{
built: make(buildIDs),
touched: make(buildIDs),
}
}
func newOpts[K any, C optionsCompiler[C]](key K, optionsID string, defaults defaultOptionValues) *opts[K, C] {
return &opts[K, C]{
key: key,
h: &optsHolder[C]{
optionsID: optionsID,
defaults: defaults,View on GitHub ↗ (pinned to 8a468df065)
Solutions
- Rename the group/script/instance ID to a flat identifier without '/', e.g. "components-nav" instead of "components/nav".
- If you need a path-like namespace, put the slashes only in the top-level js.Batch ID and keep child IDs flat.
- When deriving IDs from paths, replace slashes: {{ $id := replace .Path "/" "-" }}.
Example fix
// before
{{ $group := $batch.Group "admin/dashboard" }}
// after
{{ $group := $batch.Group "admin-dashboard" }} Defensive patterns
Strategy: validation
Validate before calling
if strings.Contains(id, "/") {
return fmt.Errorf("invalid batch id %q: forward slashes not allowed", id)
} Prevention
- Validate js.Batch identifiers at the point you construct them, before passing to the API
- Use a sanitizer (e.g. replace '/' with '-') when deriving ids from paths or slugs
- Add a template-level check when ids come from front matter or user content
When it happens
Trigger: Calling js.Batch group/script/instance/runner/config methods in templates with an ID like "my/script" for a non-top-level element, e.g. {{ $group := $batch.Group "admin/ui" }} or {{ $group.Script "foo/bar" }}. Only the batch itself (js.Batch "js/mybatch") accepts slashes.
Common situations: Developers mirror file paths in script IDs ("components/nav") when defining js.Batch groups or scripts; copying the top-level batch ID pattern (which does allow slashes) down to group/script IDs; templating IDs from page paths without sanitizing.
Related errors
- errKeyIsEmptyString
- %q is not a valid duration unit
- errMustTwoNumbersError
- strings: negative Repeat count
- error correction level must be one of low, medium, quartile,
AI-assisted analysis of gohugoio/hugo@8a468df065 (2026-07-31).
Data as JSON: /data/errors/fb1ba500edbee3b0.json.
Report an issue: GitHub ↗.