{"record":{"id":"e00ddc6c007a5cf9","repo":"plotly/plotly.js","slug":"restyle-fail","errorCode":null,"errorMessage":"Restyle fail.","messagePattern":"Restyle fail\\.","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/plot_api/plot_api.js","lineNumber":1247,"sourceCode":" *\n * `val` (or `val1`, `val2` ... in the object form) can be an array,\n * to apply different values to each trace.\n *\n * If the array is too short, it will wrap around (useful for\n * style files that want to specify cyclical default values).\n */\nfunction restyle(gd, astr, val, _traces) {\n    gd = Lib.getGraphDiv(gd);\n    helpers.clearPromiseQueue(gd);\n\n    var aobj = {};\n    if (typeof astr === 'string') aobj[astr] = val;\n    else if (Lib.isPlainObject(astr)) {\n        // the 3-arg form\n        aobj = Lib.extendFlat({}, astr);\n        if (_traces === undefined) _traces = val;\n    } else {\n        Lib.warn('Restyle fail.', astr, val, _traces);\n        return Promise.reject();\n    }\n\n    if (Object.keys(aobj).length) gd.changed = true;\n\n    var traces = helpers.coerceTraceIndices(gd, _traces);\n\n    var specs = _restyle(gd, aobj, traces);\n    var flags = specs.flags;\n\n    // clear calcdata and/or axis types if required so they get regenerated\n    if (flags.calc) gd.calcdata = undefined;\n    if (flags.clearAxisTypes) helpers.clearAxisTypes(gd, traces, {});\n\n    // fill in redraw sequence\n    var seq = [];\n\n    if (flags.fullReplot) {","sourceCodeStart":1229,"sourceCodeEnd":1265,"githubUrl":"https://github.com/plotly/plotly.js/blob/1d090e0b5ffb8d0fdf6e0e4ff51d3f3cf67f1314/src/plot_api/plot_api.js#L1229-L1265","documentation":"Plotly.restyle validates its astr argument: it must be either an attribute string ('marker.color') or a plain object mapping attributes to values (the 3-arg form). Any other type (number, array, null, etc.) cannot be converted to an attribute object, so restyle logs 'Restyle fail.' and returns a rejected promise without changing the plot.","triggerScenarios":"Plotly.restyle(gd, 42), Plotly.restyle(gd, ['marker','color'], val), Plotly.restyle(gd, null), or calling restyle with an attribute path object built dynamically that ended up undefined/non-object; also when the 3-arg form is used with a non-plain-object first arg.","commonSituations":"Dynamic attribute strings built from variables that are undefined; refactoring from relayout-style aobj calls but passing an array; framework wrappers forwarding raw event payloads as astr; TypeScript-less codebases passing wrong types after an API upgrade.","solutions":["Pass an attribute string: Plotly.restyle(gd, 'marker.color', 'red')","Or pass a plain object: Plotly.restyle(gd, {['marker.color']: 'red'}) or the 3-arg form Plotly.restyle(gd, 'marker.color', [val], [0])","Check with typeof astr === 'string' || (astr && typeof astr === 'object' && !Array.isArray(astr)) before calling","For whole-object style changes use Plotly.update instead of restyle","Handle the returned promise rejection to surface the mistake in your own error handling"],"exampleFix":"// before\nPlotly.restyle(gd, ['marker', 'color'], 'red');\n// after\nPlotly.restyle(gd, 'marker.color', 'red');","handlingStrategy":"type-guard","validationCode":"function canRestyle(astr) {\n  if (typeof astr === 'string' && astr.length) return true;\n  return astr !== null && typeof astr === 'object' && !Array.isArray(astr);\n}\nif (!canRestyle(astr)) return Promise.reject(new Error('restyle astr must be a string or plain object'));","typeGuard":"function isPlainObject(v) { return v !== null && typeof v === 'object' && !Array.isArray(v); }\nfunction isRestyleSpec(v) { return (typeof v === 'string' && v.length > 0) || isPlainObject(v); }","tryCatchPattern":"Plotly.restyle(gd, astr, val).catch(err => console.error('restyle failed for', astr, err));","preventionTips":["Always pass attribute paths as strings or a plain object of updates","Never pass arrays or event objects as the astr argument","Validate dynamically composed attribute strings are defined and non-empty","Chain .catch on restyle promises to catch bad call sites early"],"tags":["api-misuse","restyle","type-error"],"backgroundTag":"invalid-update-value","analyzedSha":"1d090e0b5ffb8d0fdf6e0e4ff51d3f3cf67f1314","analyzedAt":"2026-09-02T22:03:39.906Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T02:17:09.455Z"}