pydantic/monty · error · Error

component value node index ${index} is out of bounds

Error message

component value node index ${index} is out of bounds

What it means

readValueNode fetches a raw node from the flat value arena by index when reading class-type component values, and throws this Error when the index refers to a slot that does not exist (undefined). This means the arena sent from the sandbox (or hand-built by a caller) contains an index outside 0..nodes.length-1 — the encoded value graph is malformed.

Source

Thrown at crates/monty-js/ts/worker/value.ts:269

  validateFilePosition(position)
  return {
    tag: 'file-handle',
    val: { path: object.path, mode: canonicalFileMode(object.mode), position: BigInt(position) },
  }
}

/** Appends key/value pairs while preserving their insertion order. */
function pushPairs(pairs: [unknown, unknown][], nodes: ValueNode[]): NodePair[] {
  return pairs.map(([key, value]) => ({ key: pushValue(key, nodes), value: pushValue(value, nodes) }))
}

/** Fetches a raw arena node by index with the same bounds/cycle checks as
 *  `readValue`, for callers that must inspect the node's tag. The index stays
 *  marked as visiting, so a parent cycle in class-type nodes throws instead
 *  of recursing forever. */
function readValueNode(index: number, nodes: ValueNode[], visiting: Set<number>): ValueNode {
  const node = nodes[index]
  if (node === undefined) throw new Error(`component value node index ${index} is out of bounds`)
  if (visiting.has(index)) throw new Error('component value arena contains a cycle')
  visiting.add(index)
  return node
}

/** Reads one arena node recursively, rejecting malformed indexes and cycles. */
function readValue(index: number, nodes: ValueNode[], visiting: Set<number>): unknown {
  const node = nodes[index]
  if (node === undefined) throw new Error(`component value node index ${index} is out of bounds`)
  if (visiting.has(index)) throw new Error('component value arena contains a cycle')
  visiting.add(index)
  let value: unknown
  switch (node.tag) {
    case 'ellipsis':
      value = { [TYPE_MARKER]: 'Ellipsis' }
      break
    case 'not-implemented':
      value = { [TYPE_MARKER]: 'NotImplemented' }

View on GitHub (pinned to adc986b362)

Solutions

  1. Regenerate the arena from the source data rather than editing indexes by hand — dangling references usually mean the array and its references got out of sync.
  2. Check every reference index satisfies `0 <= i < nodes.length` before dispatching/decoding.
  3. If this comes from a worker response, update/rebuild @pydantic/monty so the Rust and TS codecs agree on the arena format.
  4. Log `nodes.length` and the offending index to find the producer of the bad reference.

Example fix

// before
nodes: [classNode],  // class node references attr value at index 1
// after
nodes: [classNode, valueNode]  // include every node the graph references
Defensive patterns

Strategy: validation

Validate before calling

function validateArena(nodes) {
  nodes.forEach((n, i) => {
    for (const ref of referencedIndexes(n)) {
      if (!(ref in nodes)) throw new Error(`node ${i} references missing index ${ref}`);
    }
  });
}

Type guard

const indexInBounds = (i: number, nodes: ValueNode[]): i is number =>
  Number.isInteger(i) && i >= 0 && i < nodes.length;

Try / catch

try {
  const value = decodeValue(nodes);
} catch (e) {
  if (e instanceof Error && e.message.includes('is out of bounds')) {
    console.error(`arena has ${nodes.length} nodes; bad ref: ${e.message}`);
  } else throw e;
}

Prevention

When it happens

Trigger: Decoding a worker response whose arena node (class attrs values, bases) references an index >= nodes.length or negative; hand-constructing a value-node arena with stale indexes after removing nodes; a bug in custom encoder code producing dangling references.

Common situations: Third-party or hand-rolled code building arenas and reusing old index constants after edits; truncating the node array without fixing references; corrupted/truncated worker messages.

Related errors


AI-assisted analysis of pydantic/monty@adc986b362 (2026-09-13). Data as JSON: /api/errors/48e7dfaafaec28ea. Report an issue: GitHub.