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

  1. Pass an attribute string: Plotly.restyle(gd, 'marker.color', 'red')
  2. Or pass a plain object: Plotly.restyle(gd, {['marker.color']: 'red'}) or the 3-arg form Plotly.restyle(gd, 'marker.color', [val], [0])
  3. Check with typeof astr === 'string' || (astr && typeof astr === 'object' && !Array.isArray(astr)) before calling
  4. For whole-object style changes use Plotly.update instead of restyle
  5. 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

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


AI-assisted analysis of plotly/plotly.js@1d090e0b5f (2026-09-02). Data as JSON: /api/errors/e00ddc6c007a5cf9. Report an issue: GitHub.