{"id":"da949606902d31ef","repo":"gohugoio/hugo","slug":"style-q-does-not-have-a-light-or-dark-mode","errorCode":null,"errorMessage":"style %q does not have a light or dark mode","messagePattern":"style %q does not have a light or dark mode","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"markup/highlight/chromastyles.go","lineNumber":119,"sourceCode":"\tvar buf bytes.Buffer\n\tif err := html.New(options...).WriteCSS(&buf, style); err != nil {\n\t\treturn \"\", err\n\t}\n\tcss := buf.String()\n\tif opts.ModeSelector {\n\t\t// Scope every selector under a top level mode class, e.g. \".dark .chroma\".\n\t\t// This allows generating both light and dark stylesheets and toggling\n\t\t// them with a parent class on the page.\n\t\t// There's no upstream option for this (I think), so do string replacements for now.\n\t\t// TODO(bep) upstream option for this.\n\t\tvar prefix string\n\t\tswitch style.Mode() {\n\t\tcase chroma.Light:\n\t\t\tprefix = \".light \"\n\t\tcase chroma.Dark:\n\t\t\tprefix = \".dark \"\n\t\tdefault:\n\t\t\treturn \"\", fmt.Errorf(\"style %q does not have a light or dark mode\", style.Name)\n\t\t}\n\t\treplacer := strings.NewReplacer(\n\t\t\t\".bg {\", prefix+\".bg {\",\n\t\t\t\".chroma \", prefix+\".chroma \",\n\t\t)\n\t\tcss = replacer.Replace(css)\n\t}\n\n\treturn css, nil\n}\n\n// chromaCSSOverrides re-emits leaf token colors that Chroma's minifier drops\n// because they equal the style's default foreground (the .chroma color). Without\n// modeSelector scoping, a paired light/dark stylesheet shares the same .chroma\n// scope, and the light sheet's explicit rule (e.g. .chroma .nx) would otherwise\n// leak into dark mode, since an explicit declaration beats inheritance.\nfunc chromaCSSOverrides(style *chroma.Style) map[chroma.TokenType]string {\n\tbg := style.Get(chroma.Background)","sourceCodeStart":101,"sourceCodeEnd":137,"githubUrl":"https://github.com/gohugoio/hugo/blob/8a468df065a75c1c7cf9f6850f32148746590ea5/markup/highlight/chromastyles.go#L101-L137","documentation":"When `ModeSelector` is enabled, Hugo scopes every generated CSS selector under a top-level `.light` or `.dark` class so both stylesheets can coexist and be toggled by a parent class. That prefix is derived from the built style's `Mode()`; if the style reports neither `chroma.Light` nor `chroma.Dark` (mode unknown/unset), Hugo cannot pick a prefix and errors instead of emitting unscoped CSS.","triggerScenarios":"Generating chromastyles CSS with the mode-selector option on, using a Chroma style whose registered mode is unspecified — typically an older or third-party style that never declared light/dark metadata. Reached only through the `opts.ModeSelector` code path in `ChromaStylesCSS`.","commonSituations":"Adopting Hugo's class-toggled light/dark highlighting scheme with a legacy style name carried over from an old config; custom or vendored Chroma styles without mode metadata; Chroma version bumps changing which styles carry mode info.","solutions":["Switch to a style that declares a light or dark mode (e.g. \"github\", \"github-dark\").","Pass an explicit `--mode=light` or `--mode=dark` so a mode-specific variant is selected up front.","Disable the mode-selector option and generate a single unscoped stylesheet if you don't need class-based theme toggling."],"exampleFix":"# before\nhugo gen chromastyles --style=some-legacy-style --modeSelector\n# after\nhugo gen chromastyles --style=github --mode=light --modeSelector","handlingStrategy":"fallback","validationCode":"// pre-check: confirm the chosen style has at least one of light/dark variants\nnames := styles.Names()\nif !slices.Contains(names, styleName) { /* reject */ }","typeGuard":null,"tryCatchPattern":"styles, err := highlight.GenerateStyles(cfg)\nif err != nil {\n    log.Printf(\"style %q lacks light/dark modes, using default: %v\", styleName, err)\n    cfg.Style = \"github\" // known dual-mode style chosen explicitly by the user\n    styles, err = highlight.GenerateStyles(cfg)\n}","preventionTips":["Pick styles known to provide both light and dark variants when using auto mode switching","Pin the style name in config and test `hugo` locally after changing it","Treat this as a config error to fix at build time, not to paper over at runtime"],"tags":["hugo","chroma","css","dark-mode","syntax-highlighting"],"analyzedSha":"8a468df065a75c1c7cf9f6850f32148746590ea5","analyzedAt":"2026-07-31T21:23:07.045Z","schemaVersion":2}