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
- Pass a string path with a value: Plotly.relayout(gd, 'xaxis.range[0]', 5)
- Or pass a plain object: Plotly.relayout(gd, {'xaxis.range': [0, 10]})
- Guard before calling: if (typeof astr !== 'string' && !Lib-like isPlainObject(astr)) return
- JSON.parse server-supplied update specs before passing them
- 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
- Parse JSON strings into objects before passing layout updates
- Never pass arrays, numbers, or undefined as the relayout spec
- Validate specs coming from servers or templates
- Keep relayout argument order (gd, astr, val) intact in wrappers
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
- Full array edits are incompatible with other edits
- Insertion & removal are incompatible with edits to the same
- Unrecognized full object edit value
- Restyle fail.
- unrecognized full object value
AI-assisted analysis of plotly/plotly.js@1d090e0b5f (2026-09-02).
Data as JSON: /api/errors/1d08936d9896c4eb.
Report an issue: GitHub.