{"record":{"id":"ccf800ff35c83e13","repo":"gohugoio/hugo","slug":"id-must-be-set","errorCode":null,"errorMessage":"id must be set","messagePattern":"id must be set","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/js/esbuild/batch.go","lineNumber":154,"sourceCode":"\nfunc (o *opts[K, C]) GetIdentity() identity.Identity {\n\treturn o.h\n}\n\nfunc (o *optsHolder[C]) SetOptions(m map[string]any) string {\n\to.optsSetCounter++\n\to.optsPrev = o.optsCurr\n\to.optsCurr = m\n\to.compiledPrev = o.compiled\n\to.compiled, o.compileErr = o.compiled.compileOptions(m, o.defaults)\n\to.checkCompileErr()\n\treturn \"\"\n}\n\n// ValidateBatchID validates the given ID according to some very\nfunc ValidateBatchID(id string, isTopLevel bool) error {\n\tif id == \"\" {\n\t\treturn fmt.Errorf(\"id must be set\")\n\t}\n\t// No Windows slashes.\n\tif strings.Contains(id, \"\\\\\") {\n\t\treturn fmt.Errorf(\"id must not contain backslashes\")\n\t}\n\n\t// Allow forward slashes in top level IDs only.\n\tif !isTopLevel && strings.Contains(id, \"/\") {\n\t\treturn fmt.Errorf(\"id must not contain forward slashes\")\n\t}\n\n\treturn nil\n}\n\nfunc newIsBuiltOrTouched() isBuiltOrTouched {\n\treturn isBuiltOrTouched{\n\t\tbuilt:   make(buildIDs),\n\t\ttouched: make(buildIDs),","sourceCodeStart":136,"sourceCodeEnd":172,"githubUrl":"https://github.com/gohugoio/hugo/blob/52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2/internal/js/esbuild/batch.go#L136-L172","documentation":"ValidateBatchID rejects an empty batch identifier (batch.go:152-154). A JS bundle batch requires a non-empty id used as a cache key and import path component; an empty id would collide and produce ambiguous virtual paths. The error is returned from ValidateBatchID and also surfaces via panic when called through BatchGroup (line 353-355).","triggerScenarios":"Calling js/esbuild batch APIs (Batcher.Group or similar) with an empty string id, or constructing a batcher whose id field was never set. Group calls ValidateBatchID(id,false) and panics on error.","commonSituations":"Programmatic batch construction where the id is derived from an unset variable; a refactor that dropped the id assignment; a template path resolving to empty.","solutions":["Provide a non-empty, slash/backslash-free id when creating or grouping batches.","Assert the id is non-empty before calling the batch API (guard at the call site).","Trace where the empty id originates (likely an unset option or empty keyPath)."],"exampleFix":"// before\ngroup := batcher.Group(ctx, \"\")\n\n// after\nif id == \"\" { return fmt.Errorf(\"batch id required\") }\ngroup := batcher.Group(ctx, id)","handlingStrategy":"validation","validationCode":"func requireBatchID(id string) error {\n    if id == \"\" {\n        return fmt.Errorf(\"id must be set\")\n    }\n    return nil\n}","typeGuard":"func isNonEmptyID(id string) bool { return id != \"\" }","tryCatchPattern":null,"preventionTips":["Always derive batch ids from non-empty, validated sources.","Guard the call site with an empty-string check to avoid Group's panic.","Unit-test batch construction with empty input to confirm the guard."],"tags":["esbuild","batch","js","validation"],"backgroundTag":null,"analyzedSha":"52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2","analyzedAt":"2026-08-09T21:49:36.660Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}