plotly/plotly.js · warning

index out of range

Error message

index out of range

What it means

For per-index edits to an array component (e.g. 'annotations.2' style edits), the componentNum index must point at an existing object (or, when the edit is an addition, one past the end). Out-of-range indices are reported with this warning and skipped via `continue`, leaving the array unchanged for that entry.

Source

Thrown at src/plot_api/manage_arrays.js:128

    var maxIndex = componentArray.length;
    var i;
    var j;
    var componentNum;
    var objEdits;
    var objKeys;
    var objVal;
    var adding, prefix;

    // first make the add and edit changes
    for(i = 0; i < componentNums.length; i++) {
        componentNum = componentNums[i];
        objEdits = edits[componentNum];
        objKeys = Object.keys(objEdits);
        objVal = objEdits[''],
        adding = isAddVal(objVal);

        if(componentNum < 0 || componentNum > componentArray.length - (adding ? 0 : 1)) {
            Loggers.warn('index out of range', componentType, componentNum);
            continue;
        }

        if(objVal !== undefined) {
            if(objKeys.length > 1) {
                Loggers.warn(
                    'Insertion & removal are incompatible with edits to the same index.',
                    componentType, componentNum);
            }

            if(isRemoveVal(objVal)) {
                deletes.push(componentNum);
            } else if(adding) {
                if(objVal === 'add') objVal = {};
                componentArray.splice(componentNum, 0, objVal);
                if(componentArrayFull) componentArrayFull.splice(componentNum, 0, {});
            } else {
                Loggers.warn('Unrecognized full object edit value',

View on GitHub (pinned to 1d090e0b5f)

Solutions

  1. Check the current array length (gd.layout[componentType].length) and clamp/skip the index before the edit.
  2. Use the 'adding' form (value = new object) when you actually want to append at index === length.
  3. Re-read the layout array before batch edits instead of using cached lengths.
  4. Verify index arithmetic for loops (i < arr.length, i >= 0).

Example fix

// before
edits[idx] = { text: 'x' }; // idx may exceed array length
// after
if (idx >= 0 && idx < gd.layout.annotations.length) {
  edits[idx] = { text: 'x' };
}
Defensive patterns

Strategy: validation

Validate before calling

function assertIndexInRange(gd, componentType, num, adding) {
  const arr = gd.layout[componentType] || [];
  if (num < 0 || num > arr.length - (adding ? 0 : 1)) {
    throw new RangeError(`${componentType} index ${num} out of range (len ${arr.length})`);
  }
}

Type guard

function inRange(num, len, adding) { return Number.isInteger(num) && num >= 0 && num <= len - (adding ? 0 : 1); }

Prevention

When it happens

Trigger: Editing 'annotations[5]' when only 3 annotations exist; removing (or editing, non-adding) an index equal to array length; negative component numbers from decrement loops.

Common situations: React/update calls derived from stale UI state after items were deleted elsewhere, off-by-one errors (index === length), and batch edits computed against a previous array snapshot.

Related errors


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