plotly/plotly.js · warning
trace index ( ${index} ) is not a number or is out of bounds
Error message
trace index ( ${index} ) is not a number or is out of bounds What it means
Helpers that operate on traces (e.g. deleteTraces, moveTraces, extend/prepend traces) validate each requested trace index with Lib.isIndex against gd.data.length. A non-numeric or out-of-bounds entry is reported via this warning and silently dropped from the resulting index list instead of throwing.
Source
Thrown at src/plot_api/helpers.js:386
trace.hoverinfo = hoverInfoParts.join('+');
}
};
// coerce traceIndices input to array of trace indices
exports.coerceTraceIndices = function (gd, traceIndices) {
if (isNumeric(traceIndices)) {
return [traceIndices];
} else if (!Array.isArray(traceIndices) || !traceIndices.length) {
return gd.data.map(function (_, i) {
return i;
});
} else if (Array.isArray(traceIndices)) {
var traceIndicesOut = [];
for (var i = 0; i < traceIndices.length; i++) {
if (Lib.isIndex(traceIndices[i], gd.data.length)) {
traceIndicesOut.push(traceIndices[i]);
} else {
Lib.warn('trace index (', traceIndices[i], ') is not a number or is out of bounds');
}
}
return traceIndicesOut;
}
return traceIndices;
};
/**
* Manages logic around array container item creation / deletion / update
* that nested property alone can't handle.
*
* @param {Object} np
* nested property of update attribute string about trace or layout object
* @param {*} newVal
* update value passed to restyle / relayout / update
* @param {Object} undoit
* undo hash (N.B. undoit may be mutated here).View on GitHub (pinned to 1d090e0b5f)
Solutions
- Validate indices before the call: 0 <= i < gd.data.length and typeof i === 'number'.
- Refresh any cached indices from gd.data immediately before operating on traces.
- Debounce/double-submit-guard UI actions that delete or move traces.
- Pass trace UIDs or objects instead of raw indices where the API accepts them, to avoid stale-position bugs.
Example fix
// before
Plotly.deleteTraces(gd, [idx]); // idx may be stale/NaN
// after
if (Number.isInteger(idx) && idx >= 0 && idx < gd.data.length) {
Plotly.deleteTraces(gd, [idx]);
} Defensive patterns
Strategy: type-guard
Validate before calling
function validTraceIndices(gd, idxs) {
return (Array.isArray(idxs) ? idxs : [idxs])
.filter(i => Number.isInteger(i) && i >= 0 && i < gd.data.length);
} Type guard
function isValidTraceIndex(i, gd) { return Number.isInteger(i) && i >= 0 && i < gd.data.length; } Prevention
- Recompute indices from gd.data immediately before trace operations.
- Filter arrays of indices with isValidTraceIndex before passing them.
- Guard UI delete/move actions against double submission.
- Prefer trace uids over positional indices for long-lived references.
When it happens
Trigger: Calling Plotly.deleteTraces(gd, [0, 5]) when gd.data has fewer than 6 traces, passing a string like '1' or null/undefined as an index, or passing an index computed from stale state after a previous deletion.
Common situations: React/Vue apps keeping stale trace indices after data updates, user-driven deletion buttons acting twice (double click), and off-by-one loops over trace arrays.
Related errors
AI-assisted analysis of plotly/plotly.js@1d090e0b5f (2026-09-02).
Data as JSON: /api/errors/abf6550ad51462e9.
Report an issue: GitHub.