plotly/plotly.js · error
Restyle fail.
Error message
Restyle fail.
What it means
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.
Source
Thrown at src/plot_api/plot_api.js:1247
*
* `val` (or `val1`, `val2` ... in the object form) can be an array,
* to apply different values to each trace.
*
* If the array is too short, it will wrap around (useful for
* style files that want to specify cyclical default values).
*/
function restyle(gd, astr, val, _traces) {
gd = Lib.getGraphDiv(gd);
helpers.clearPromiseQueue(gd);
var aobj = {};
if (typeof astr === 'string') aobj[astr] = val;
else if (Lib.isPlainObject(astr)) {
// the 3-arg form
aobj = Lib.extendFlat({}, astr);
if (_traces === undefined) _traces = val;
} else {
Lib.warn('Restyle fail.', astr, val, _traces);
return Promise.reject();
}
if (Object.keys(aobj).length) gd.changed = true;
var traces = helpers.coerceTraceIndices(gd, _traces);
var specs = _restyle(gd, aobj, traces);
var flags = specs.flags;
// clear calcdata and/or axis types if required so they get regenerated
if (flags.calc) gd.calcdata = undefined;
if (flags.clearAxisTypes) helpers.clearAxisTypes(gd, traces, {});
// fill in redraw sequence
var seq = [];
if (flags.fullReplot) {View on GitHub (pinned to 1d090e0b5f)
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
Example fix
// before Plotly.restyle(gd, ['marker', 'color'], 'red'); // after Plotly.restyle(gd, 'marker.color', 'red');
Defensive patterns
Strategy: type-guard
Validate before calling
function canRestyle(astr) {
if (typeof astr === 'string' && astr.length) return true;
return astr !== null && typeof astr === 'object' && !Array.isArray(astr);
}
if (!canRestyle(astr)) return Promise.reject(new Error('restyle astr must be a string or plain object')); Type guard
function isPlainObject(v) { return v !== null && typeof v === 'object' && !Array.isArray(v); }
function isRestyleSpec(v) { return (typeof v === 'string' && v.length > 0) || isPlainObject(v); } Try / catch
Plotly.restyle(gd, astr, val).catch(err => console.error('restyle failed for', astr, err)); Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Relayout fail.
- Full array edits are incompatible with other edits
- Insertion & removal are incompatible with edits to the same
- Unrecognized full object edit value
- unrecognized full object value
AI-assisted analysis of plotly/plotly.js@1d090e0b5f (2026-09-02).
Data as JSON: /api/errors/e00ddc6c007a5cf9.
Report an issue: GitHub.