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

  1. Validate indices before the call: 0 <= i < gd.data.length and typeof i === 'number'.
  2. Refresh any cached indices from gd.data immediately before operating on traces.
  3. Debounce/double-submit-guard UI actions that delete or move traces.
  4. 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

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.