{"record":{"id":"6c222170374cee06","repo":"gohugoio/hugo","slug":"targetpath-cannot-be-empty","errorCode":null,"errorMessage":"targetPath cannot be empty","messagePattern":"targetPath cannot be empty","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"tpl/css/css.go","lineNumber":73,"sourceCode":"// markup.highlight.noClasses is disabled in config.\n// The style defaults to the markup.highlight.style config setting.\nfunc (ns *Namespace) ChromaStyles(opts any) (resource.Resource, error) {\n\tkey := hashing.HashUint64(opts)\n\treturn ns.chromaStylesCache.GetOrCreate(key, func() (resource.Resource, error) {\n\t\tm, err := hmaps.ToStringMapE(opts)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tvar o struct {\n\t\t\tTargetPath                    string\n\t\t\thighlight.ChromaStylesOptions `mapstructure:\",squash\"`\n\t\t}\n\n\t\tif err := mapstructure.WeakDecode(m, &o); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif o.TargetPath == \"\" {\n\t\t\treturn nil, errors.New(\"targetPath cannot be empty\")\n\t\t}\n\t\tif o.Style == \"\" {\n\t\t\to.Style = ns.highlightConfig.Style\n\t\t}\n\t\tcss, err := highlight.ChromaStylesCSS(o.ChromaStylesOptions)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\treturn ns.d.ResourceSpec.NewResource(\n\t\t\tresources.ResourceSourceDescriptor{\n\t\t\t\tLazyPublish:   true,\n\t\t\t\tGroupIdentity: identity.Anonymous,\n\t\t\t\tOpenReadSeekCloser: func() (hugio.ReadSeekCloser, error) {\n\t\t\t\t\treturn hugio.NewReadSeekerNoOpCloserFromString(css), nil\n\t\t\t\t},\n\t\t\t\tTargetPath: o.TargetPath,\n\t\t\t})","sourceCodeStart":55,"sourceCodeEnd":91,"githubUrl":"https://github.com/gohugoio/hugo/blob/52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2/tpl/css/css.go#L55-L91","documentation":"The `css.ChromaStyles` function generates a syntax-highlighting stylesheet. Its options dict must include a `targetPath` so Hugo knows where to publish the generated CSS. After decoding the options struct, if `TargetPath` is empty, this error fires at css.go:72–73.","triggerScenarios":"Calling `{{ (css.ChromaStyles (dict \"style\" \"monokai\")) }}` without a `targetPath` key, or passing an empty string: `{{ (css.ChromaStyles (dict \"targetPath\" \"\" \"style\" \"dracula\")) }}`.","commonSituations":"A developer copies a ChromaStyles example but drops or renames the `targetPath` key (e.g. uses `target` or `path` instead). The config decode silently leaves TargetPath empty.","solutions":["Add `targetPath` to the options dict: `{{ (css.ChromaStyles (dict \"targetPath\" \"css/chroma.css\" \"style\" \"monokai\")) }}`.","Use the exact key name `targetPath` (case-insensitive via mapstructure).","Verify the dict is non-nil and contains the key before the call."],"exampleFix":"// before\n{{ (css.ChromaStyles (dict \"style\" \"monokai\")) }}\n// after\n{{ (css.ChromaStyles (dict \"targetPath\" \"css/chroma.css\" \"style\" \"monokai\")) }}","handlingStrategy":"validation","validationCode":"{{ $opts := dict \"targetPath\" \"css/chroma.css\" \"style\" \"monokai\" }}\n{{ if $opts.targetPath }}{{ (css.ChromaStyles $opts) }}{{ end }}","typeGuard":"func hasTargetPath(opts map[string]any) bool {\n    tp, _ := opts[\"targetPath\"].(string)\n    return tp != \"\"\n}","tryCatchPattern":null,"preventionTips":["Always include `targetPath` in the ChromaStyles options dict.","Use the exact key name `targetPath` (case-insensitive).","Validate the dict is non-nil and contains the key."],"tags":["hugo","template","css","chroma","config"],"backgroundTag":null,"analyzedSha":"52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2","analyzedAt":"2026-08-09T21:49:36.660Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}