{"record":{"id":"c8f6866e01c987e4","repo":"plotly/plotly.js","slug":"invalid-color-specifier-cstr-defaulting-to","errorCode":null,"errorMessage":"Invalid color specifier: \"${cstr}\". Defaulting to \"#000\"","messagePattern":"Invalid color specifier: \"(.+?)\"\\. Defaulting to \"#000\"","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"src/components/color/index.js","lineNumber":77,"sourceCode":"// 8-bit step first. Six decimals absorb the float error and still leave a\n// genuine value such as 122.45 alone.\nconst snap01 = (v) => Math.round(v * 255e6) / 255e6;\nconst snap = (c) => ({ ...c, r: snap01(c.r), g: snap01(c.g), b: snap01(c.b) });\n\nconst formatRgb = (c) => culoriFormatRgb(snap(c));\nconst formatHex = (c) => culoriFormatHex(snap(c));\n\n/**\n * Parse a color specifier string and return it as a culori rgb color object.\n *\n * @param {*} cstr - Color specifier\n * @param {Boolean} [silent] - Skip the warning, for callers that run per data point\n * @return {Object} A culori rgb color ({ mode: 'rgb', r: _, g: _, b: _, alpha: _ })\n */\nconst parse = (cstr, silent) => {\n    const c = toColor(cstr);\n    if (!c) {\n        if (!silent && cstr != null) warn(`Invalid color specifier: \"${cstr}\". Defaulting to \"#000\"`);\n        return BLACK;\n    }\n    // `toRgb` omits alpha when it's 1; make sure it's added since we expect it\n    c.alpha ??= 1;\n\n    return c;\n};\n\n// TODO: rename to `rgbString` to better describe return value\n/**\n * Convert any color specifier to a normalized `rgb(r, g, b)` string.\n * Force alpha to 1 so that it gets dropped in the result.\n *\n * @param {*} cstr - Color specifier\n * @return {String}\n */\nconst rgb = (cstr) => formatRgb({ ...parse(cstr), alpha: 1 });\n","sourceCodeStart":59,"sourceCodeEnd":95,"githubUrl":"https://github.com/plotly/plotly.js/blob/1d090e0b5ffb8d0fdf6e0e4ff51d3f3cf67f1314/src/components/color/index.js#L59-L95","documentation":"plotly.js parses all color-like strings through culori-based `parse`. When the string cannot be converted to an RGB color, it warns 'Invalid color specifier' and falls back to black (#000). It exists because plotting silently using undefined colors is confusing; the warning points at the malformed input.","triggerScenarios":"Setting any color attribute (marker.color, line.color, layout colorway, font color, colorscale stop values) to a string culori cannot parse — e.g. 'not-a-color', a misspelled keyword ('rebeccapurplee'), an out-of-gamut CSS4 color, an rgba() string with the wrong argument count, or a number where a string is expected.","commonSituations":"Colors coming from user data or API responses that were assumed valid; typos in CSS color names; using 'rgb(r,g,b)' with percentages mixed with numbers; passing a hex string missing the '#' or with 5 digits.","solutions":["Log the cstr value in the warning and correct the offending data at its source.","Use parse-silent-friendly inputs: hex (#rgb, #rrggbb, #rrggbbaa), rgb()/rgba()/hsl()/hsla() strings, or valid CSS named colors.","Validate colors before assignment with a regex or the browser (e.g. assigning to a temporary element's style.color and comparing).","Use a colorscale object/array for per-point coloring instead of raw strings from data.","Guard optional attributes: only set color when the value is a non-empty string."],"exampleFix":"// before\nPlotly.restyle(gd, 'marker.color', trace.color || 'auto'); // 'auto' is invalid\n// after\nconst color = /^#([0-9a-f]{3,8})$/i.test(trace.color || '') ? trace.color : '#000000';\nPlotly.restyle(gd, 'marker.color', color);","handlingStrategy":"validation","validationCode":"function isValidColor(c) {\n  if (typeof c !== 'string') return false;\n  const s = new Option().style;\n  s.color = '';\n  s.color = c;\n  return s.color !== '';\n}","typeGuard":"function isColorString(v) {\n  return typeof v === 'string' && isValidColor(v);\n}","tryCatchPattern":"// plotly only warns (no throw), so prefer pre-validation\nif (!isValidColor(color)) {\n  console.warn('rejecting bad color', color);\n  color = '#000000';\n}\nPlotly.restyle(gd, 'marker.color', color);","preventionTips":["Only pass hex, rgb()/rgba()/hsl()/hsla() strings, or valid CSS named colors.","Never trust colors from user input or APIs — validate before assignment.","Test suspicious colors with a temporary DOM element's style.color round-trip.","For per-point colors, prefer arrays of valid strings or a colorscale + cmin/cmax."],"tags":["color","validation","fallback"],"backgroundTag":"invalid-color-format","analyzedSha":"1d090e0b5ffb8d0fdf6e0e4ff51d3f3cf67f1314","analyzedAt":"2026-09-02T22:03:39.906Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T02:17:09.455Z"}