can1357/oh-my-pi · error

rpc chunk sequence must start at index 0

Error message

rpc chunk sequence must start at index 0

What it means

When no reassembly is in progress (#pending undefined), the first rpc_chunk received must carry index 0. This error is thrown when a decoder that has not seen any chunks receives a continuation chunk (index > 0), meaning the start of the chunked sequence was lost or skipped.

Source

Thrown at packages/coding-agent/src/modes/rpc/rpc-frame.ts:165

			typeof chunkId !== "string" ||
			chunkId.length === 0 ||
			chunkId.length > 128 ||
			!Number.isSafeInteger(index) ||
			!Number.isSafeInteger(count) ||
			!Number.isSafeInteger(byteLength) ||
			index < 0 ||
			count < 2 ||
			count > Math.ceil(MAX_RPC_REASSEMBLED_BYTES / RPC_CHUNK_PAYLOAD_BYTES) ||
			index >= count ||
			byteLength < MAX_RPC_FRAME_BYTES ||
			byteLength > MAX_RPC_REASSEMBLED_BYTES
		)
			throw new Error("invalid rpc chunk metadata");
		const bytes = decodeBase64(value.data);
		if (bytes.byteLength > RPC_CHUNK_PAYLOAD_BYTES) throw new Error("rpc chunk payload exceeds the transport limit");

		if (!this.#pending) {
			if (index !== 0) throw new Error("rpc chunk sequence must start at index 0");
			this.#pending = { chunkId, count, byteLength, nextIndex: 0, chunks: [], receivedBytes: 0 };
		}
		const pending = this.#pending;
		if (
			pending.chunkId !== chunkId ||
			pending.count !== count ||
			pending.byteLength !== byteLength ||
			pending.nextIndex !== index
		)
			throw new Error("rpc chunk sequence mismatch");
		pending.chunks.push(bytes);
		pending.receivedBytes += bytes.byteLength;
		pending.nextIndex++;
		if (pending.receivedBytes > pending.byteLength) throw new Error("rpc chunk sequence exceeds declared length");
		if (pending.nextIndex < pending.count) return undefined;
		if (pending.receivedBytes !== pending.byteLength) throw new Error("rpc chunk sequence length mismatch");

		this.#pending = undefined;

View on GitHub (pinned to 9690622007)

Solutions

  1. Consume the RPC stream from its beginning so chunk 0 of every sequence is seen.
  2. On any sequence error, reset (recreate the decoder) and re-request the frame rather than continuing mid-sequence.
  3. Ensure the transport is reliable (no line drops) between sender and decoder.

Example fix

// before: late-attaching decoder to an in-flight stream
const decoder = new RpcFrameDecoder(); stream.pipe(lateHandler);
// after: restart the stream so the sequence begins at index 0
restartStream(); // then pipe all lines from the start
Defensive patterns

Strategy: try-catch

Try / catch

try {
  const frame = decoder.push(parsedLine);
} catch (err) {
  if (err instanceof Error && err.message === "rpc chunk sequence must start at index 0") {
    // stream was joined mid-sequence: restart the source and recreate the decoder
    decoder = new RpcFrameDecoder();
    restartStreamFromBeginning();
  } else throw err;
}

Prevention

When it happens

Trigger: Starting to read the stream mid-sequence (decoder created after the sender already emitted chunk 0); chunk 0 dropped by an intermediate transport; reusing a fresh decoder to replay a capture that begins mid-frame.

Common situations: Attaching to a long-running agent's RPC stream late (tail-follow); log rotation or pipe buffering that discarded early lines; resuming after an error without restarting the sequence.

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/c4df4d2f367d2144. Report an issue: GitHub.