{"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/8a468df065a75c1c7cf9f6850f32148746590ea5/tpl/css/css.go#L55-L91","documentation":"css.ChromaStyles generates a CSS stylesheet resource for Chroma syntax highlighting classes. The options map must include a targetPath telling Hugo where to publish the generated CSS; unlike style (which defaults from markup.highlight.style), targetPath has no default, so an empty value is rejected.","triggerScenarios":"Calling {{ transform.ToCSS }}-style helper css.ChromaStyles with an options dict missing targetPath, with targetPath set to \"\", or with a misspelled key (e.g. targetpath decodes fine via WeakDecode but 'target_path' or 'path' does not).","commonSituations":"Users adding class-based highlighting (markup.highlight.noClasses = false) copy an example that omits targetPath, or pass the style name as a bare string instead of a dict.","solutions":["Pass targetPath in the options dict: {{ $css := css.ChromaStyles (dict \"targetPath\" \"css/chroma.css\") }}.","Check the key spelling — it must decode to TargetPath (targetPath/targetpath work; underscored variants do not).","Ensure you pass a dict, not just the style string."],"exampleFix":"{{/* before */}}\n{{ $css := css.ChromaStyles (dict \"style\" \"dracula\") }}\n\n{{/* after */}}\n{{ $css := css.ChromaStyles (dict \"style\" \"dracula\" \"targetPath\" \"css/chroma.css\") }}","handlingStrategy":"validation","validationCode":"{{ $target := \"css/main.css\" }}\n{{ if not $target }}\n  {{ errorf \"css target path must be set\" }}\n{{ end }}\n{{ $css := resources.Get \"sass/main.scss\" | css.Sass (dict \"targetPath\" $target) }}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never pass an empty or unset variable as targetPath to css functions","When targetPath comes from site params, assert it with errorf early in the template","Prefer literal target paths over computed ones where possible"],"tags":["hugo","css","chroma","syntax-highlighting","template-functions"],"analyzedSha":"8a468df065a75c1c7cf9f6850f32148746590ea5","analyzedAt":"2026-07-31T21:23:07.045Z","schemaVersion":2}