plotly/plotly.js · error

Relayout fail.

Error message

Relayout fail.

What it means

Plotly.relayout requires its astr argument to be an attribute string ('xaxis.range[0]') or a plain object of attribute/value pairs. Any other type cannot form the update object, so relayout logs 'Relayout fail.' and returns a rejected promise; the layout is left unchanged.

Source

Thrown at src/plot_api/plot_api.js:1708

 *
 * Signature 2:
 * @param {String | HTMLDivElement} gd
 *  (as in signature 1)
 * @param {Object} aobj
 *  attribute object `{astr1: val1, astr2: val2 ...}`
 *  allows setting multiple attributes simultaneously
 */
function relayout(gd, astr, val) {
    gd = Lib.getGraphDiv(gd);
    helpers.clearPromiseQueue(gd);

    var aobj = {};
    if (typeof astr === 'string') {
        aobj[astr] = val;
    } else if (Lib.isPlainObject(astr)) {
        aobj = Lib.extendFlat({}, astr);
    } else {
        Lib.warn('Relayout fail.', astr, val);
        return Promise.reject();
    }

    if (Object.keys(aobj).length) gd.changed = true;

    var specs = _relayout(gd, aobj);
    var flags = specs.flags;

    // clear calcdata if required
    if (flags.calc) gd.calcdata = undefined;

    // fill in redraw sequence

    // even if we don't have anything left in aobj,
    // something may have happened within relayout that we
    // need to wait for
    var seq = [Plots.previousPromises];
    if (flags.layoutReplot) {

View on GitHub (pinned to 1d090e0b5f)

Solutions

  1. Pass a string path with a value: Plotly.relayout(gd, 'xaxis.range[0]', 5)
  2. Or pass a plain object: Plotly.relayout(gd, {'xaxis.range': [0, 10]})
  3. Guard before calling: if (typeof astr !== 'string' && !Lib-like isPlainObject(astr)) return
  4. JSON.parse server-supplied update specs before passing them
  5. Chain .catch on the returned promise to detect and log the bad call site

Example fix

// before
Plotly.relayout(gd, JSON.stringify({'yaxis.range': [0, 5]}));
// after
Plotly.relayout(gd, JSON.parse(jsonSpec));
Defensive patterns

Strategy: type-guard

Validate before calling

function canRelayout(astr) {
  if (typeof astr === 'string' && astr.length) return true;
  return astr !== null && typeof astr === 'object' && !Array.isArray(astr);
}
if (!canRelayout(spec)) throw new TypeError('relayout spec must be a string or plain object');

Type guard

function isPlainObject(v) { return v !== null && typeof v === 'object' && !Array.isArray(v); }
function isRelayoutSpec(v) { return (typeof v === 'string' && v.length > 0) || isPlainObject(v); }

Try / catch

Plotly.relayout(gd, astr, val).catch(err => console.error('relayout failed for', astr, err));

Prevention

When it happens

Trigger: Plotly.relayout(gd, 123), Plotly.relayout(gd, undefined), Plotly.relayout(gd, someArray), or forwarding a non-object payload (e.g. JSON string, DOM event) as the update spec.

Common situations: Parsing layout updates from a server and forgetting JSON.parse; passing React state objects that are actually arrays; calling relayout with only (gd) in an event handler whose args shifted after a plotly.js major-version upgrade; wrapper libraries misfwding arguments.

Related errors


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