{"record":{"id":"8b857a76ecbc2cd4","repo":"can1357/oh-my-pi","slug":"invalid-color-value-color","errorCode":null,"errorMessage":"Invalid color value: ${color}","messagePattern":"Invalid color value: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/modes/theme/color.ts","lineNumber":19,"sourceCode":"import { detectTerminalId, getTerminalInfo } from \"@oh-my-pi/pi-tui\";\nimport type { ColorMode, ColorValue } from \"./schema\";\n\n// ============================================================================\n// Color Utilities\n// ============================================================================\n\n/** Resolve theme color depth from the shared terminal capability model. */\nexport function detectColorMode(env: NodeJS.ProcessEnv = Bun.env): ColorMode {\n\tif (env.WT_SESSION) return \"truecolor\";\n\tconst terminal = getTerminalInfo(detectTerminalId(env), process.platform, env);\n\treturn terminal.trueColor ? \"truecolor\" : \"256color\";\n}\n\nexport function colorToAnsi(color: string, mode: ColorMode): string {\n\tconst format = mode === \"truecolor\" ? \"ansi-16m\" : \"ansi-256\";\n\tconst ansi = Bun.color(color, format);\n\tif (ansi === null) {\n\t\tthrow new Error(`Invalid color value: ${color}`);\n\t}\n\treturn ansi;\n}\n\nexport function fgAnsi(color: string | number, mode: ColorMode): string {\n\tif (color === \"\") return \"\\x1b[39m\";\n\tif (typeof color === \"number\") return `\\x1b[38;5;${color}m`;\n\tif (typeof color === \"string\") {\n\t\treturn colorToAnsi(color, mode);\n\t}\n\tthrow new Error(`Invalid color value: ${color}`);\n}\n\nexport function bgAnsi(color: string | number, mode: ColorMode): string {\n\tif (color === \"\") return \"\\x1b[49m\";\n\tif (typeof color === \"number\") return `\\x1b[48;5;${color}m`;\n\tconst ansi = colorToAnsi(color, mode);\n\treturn ansi.replace(\"\\x1b[38;\", \"\\x1b[48;\");","sourceCodeStart":1,"sourceCodeEnd":37,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/modes/theme/color.ts#L1-L37","documentation":"colorToAnsi converts a theme color string to an ANSI escape sequence using Bun.color for the target mode (truecolor/ansi-256). If Bun.color cannot parse the value (null result), the color string is invalid for that conversion and this error is thrown with the offending value included. Theme loading calls this for every color, so one bad entry aborts the conversion.","triggerScenarios":"Passing a color string Bun.color cannot parse — e.g. an unrecognized name ('notacolor'), malformed hex ('#12345'), a CSS function with wrong syntax ('rgb(300)'), or an empty/garbage string — while converting in either truecolor or 256-color mode.","commonSituations":"Custom theme files with typo'd or out-of-gamut colors; themes hand-edited where a value was deleted or truncated; colors copied from web CSS using formats Bun doesn't parse; programmatic theme generation producing empty strings.","solutions":["Fix the color value in the theme to a valid CSS color (e.g. '#ff5500', 'rgb(255,85,0)', or a known name).","Validate theme colors with Bun.color(value, \"ansi-16m\") !== null before applying the theme, falling back to a default color per slot.","Check for truncated/empty strings from config loading (missing key, wrong file format)."],"exampleFix":"// before\nconst fg = colorToAnsi(\"#12345\", mode); // malformed hex -> throws\n// after\nconst fg = colorToAnsi(\"#112345\", mode);","handlingStrategy":"validation","validationCode":"function isValidColor(value: string): boolean {\n  return Bun.color(value, \"ansi-16m\") !== null;\n}\n// validate each theme color before applying; substitute defaults for invalid entries","typeGuard":null,"tryCatchPattern":"try {\n  ansi = colorToAnsi(color, mode);\n} catch (err) {\n  if (err instanceof Error && err.message.startsWith(\"Invalid color value:\")) {\n    ansi = colorToAnsi(\"#808080\", mode); // safe fallback\n  } else throw err;\n}","preventionTips":["Validate all colors at theme-load time and fall back per slot instead of throwing mid-render.","Use canonical CSS color syntax: 3/6-digit hex, rgb()/hsl() functions, or standard names.","Watch for truncated values from hand-edited theme files and empty strings from missing config keys."],"tags":["color","theme","validation","ansi"],"backgroundTag":"invalid-color-value","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}