{"record":{"id":"b26e4647f5c8d53c","repo":"d2lang/d2","slug":"invalid-luminance-category","errorCode":null,"errorMessage":"invalid luminance category","messagePattern":"invalid luminance category","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"d2renderers/d2svg/d2svg.go","lineNumber":3394,"sourceCode":"\t\tout += \".light-code{display: block}\"\n\t\tout += \".dark-code{display: none}\"\n\t}\n\n\treturn out, nil\n}\n\nfunc blendMode(lc string) string {\n\tswitch lc {\n\tcase \"bright\":\n\t\treturn \"darken\"\n\tcase \"normal\":\n\t\treturn \"color-burn\"\n\tcase \"dark\":\n\t\treturn \"overlay\"\n\tcase \"darker\":\n\t\treturn \"lighten\"\n\t}\n\tpanic(\"invalid luminance category\")\n}\n\ntype DiagramObject interface {\n\tGetID() string\n\tGetZIndex() int\n}\n\n// sortObjects sorts all diagrams objects (shapes and connections) in the desired drawing order\n// the sorting criteria is:\n// 1. zIndex, lower comes first\n// 2. two shapes with the same zIndex are sorted by their level (container nesting), containers come first\n// 3. two shapes with the same zIndex and same level, are sorted in the order they were exported\n// 4. shape and edge, shapes come first\nfunc sortObjects(allObjects []DiagramObject) {\n\tsort.SliceStable(allObjects, func(i, j int) bool {\n\t\t// first sort by zIndex\n\t\tiZIndex := allObjects[i].GetZIndex()\n\t\tjZIndex := allObjects[j].GetZIndex()","sourceCodeStart":3376,"sourceCodeEnd":3412,"githubUrl":"https://github.com/d2lang/d2/blob/0d69dca6f532ceaeacd615d35d1eaa41a238ffdb/d2renderers/d2svg/d2svg.go#L3376-L3412","documentation":"blendMode maps a luminance category string (\"bright\", \"normal\", \"dark\", \"darker\") to an SVG mix-blend-mode used by sketch-style overlay themes. The categories come from theme color fields; if a luminance value outside the four known categories reaches this function, it panics. It is an internal invariant protecting against malformed themes.","triggerScenarios":"Rendering with an inline/custom theme whose color luminance category (derived from theme color fields like N7 via luminance helpers) is not one of \"bright\"/\"normal\"/\"dark\"/\"darker\" when d2svg applies sketch streak overlays.","commonSituations":"Hand-written custom theme JSON with colors yielding an unexpected luminance bucket; theme fields set to arbitrary strings in programmatic theme construction; theme version drift where a new category was added but blendMode not updated.","solutions":["Fix the custom theme's color values so the computed luminance falls into a supported category","Only use known luminance category values when constructing themes programmatically","Patch blendMode to handle the new category if you intentionally introduced one","Test custom themes through d2svg Render before shipping; fall back to the default theme if rendering panics"],"exampleFix":"// before\ntheme.Color.N7 = \"#12345678\" // 8-digit hex yields unknown luminance\n// after\ntheme.Color.N7 = \"#123456\" // standard hex in supported range","handlingStrategy":"validation","validationCode":"// Validate custom theme colors produce a supported luminance category before Render\ncat := luminanceToCategory(theme.Color.N7)\nswitch cat {\ncase \"bright\", \"normal\", \"dark\", \"darker\":\ndefault:\n    return fmt.Errorf(\"theme color %q yields invalid luminance category %q\", theme.Color.N7, cat)\n}","typeGuard":"func validLuminanceCategory(lc string) bool {\n    switch lc {\n    case \"bright\", \"normal\", \"dark\", \"darker\":\n        return true\n    }\n    return false\n}","tryCatchPattern":"// Recover around Render when using custom themes\ndefer func() {\n    if r := recover(); r != nil {\n        if s, ok := r.(string); ok && s == \"invalid luminance category\" {\n            err = fmt.Errorf(\"theme has invalid luminance category\")\n        } else { panic(r) }\n    }\n}()","preventionTips":["Derive custom themes from the default theme rather than inventing color fields","Use standard 6/8-digit sRGB hex colors in themes","Test any custom theme through d2svg Render before release","Update blendMode when introducing new luminance categories"],"tags":["go","panic","svg","theming","sketch","luminance"],"backgroundTag":"invalid-luminance-category","analyzedSha":"0d69dca6f532ceaeacd615d35d1eaa41a238ffdb","analyzedAt":"2026-08-31T12:19:21.182Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}