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
- Consume the RPC stream from its beginning so chunk 0 of every sequence is seen.
- On any sequence error, reset (recreate the decoder) and re-request the frame rather than continuing mid-sequence.
- 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
- Consume the stream from its start; never tail-join an RPC channel mid-frame.
- Reset decoder state on reconnect.
- Make the transport drop-free (pipes, not lossy logs).
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
- rpc chunk sequence interrupted
- rpc chunk sequence mismatch
- Replacement text is not valid UTF-8: {err}
- invalid glob `{pattern}`: {error}
- RPC chunk received before protocol negotiation
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/c4df4d2f367d2144.
Report an issue: GitHub.