can1357/oh-my-pi · error
rpc chunk sequence mismatch
Error message
rpc chunk sequence mismatch
What it means
Once reassembly is in progress, every subsequent rpc_chunk must match the pending sequence exactly: same chunkId, count, and byteLength, and its index must equal the expected nextIndex. This error is thrown when any of those fields differs — the chunk belongs to a different sequence, the header was mutated, or chunks arrived out of order or duplicated.
Source
Thrown at packages/coding-agent/src/modes/rpc/rpc-frame.ts:175
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;
const decoded = new TextDecoder("utf-8", { fatal: true }).decode(Buffer.concat(pending.chunks));
const frame: unknown = JSON.parse(decoded);
if (!isRecord(frame)) throw new Error("rpc frame must be an object");
return frame;
}
}
function compactTerminalFrame(
frame: object,
streamedMessageCount: number,View on GitHub (pinned to 9690622007)
Solutions
- Send chunks strictly in index order, exactly once per sequence, on a single stream.
- Keep chunkId/count/byteLength immutable for the whole sequence — compute them once before emitting chunk 0.
- On a failed/retried send, restart the sequence with a NEW chunkId from index 0 and reset the decoder.
- Serialize chunk emission with a queue if multiple producers share the stream.
Example fix
// before: retry reuses old chunkId mid-stream
write(frameChunks); // first attempt partially sent
write(frameChunks); // duplicate chunkId, wrong nextIndex
// after: new sequence id and decoder reset
const chunkId = `rpc-${crypto.randomUUID()}`;
write(frameChunks.map(c => ({ ...c, chunkId }))); Defensive patterns
Strategy: try-catch
Validate before calling
// client-side sequencing check before writing the next chunk
if (pendingState && (chunk.chunkId !== pendingState.chunkId || chunk.index !== pendingState.nextIndex)) {
throw new Error("sender bug: chunk does not continue the open sequence");
} Try / catch
try {
const frame = decoder.push(parsedLine);
} catch (err) {
if (err instanceof Error && err.message === "rpc chunk sequence mismatch") {
decoder = new RpcFrameDecoder(); // discard stale sequence; re-request the logical frame
} else throw err;
} Prevention
- One chunked sequence at a time per stream; queue concurrent senders.
- Never retry a chunk write without a fresh chunkId and index 0 restart.
- Compute chunkId/count/byteLength once per frame and freeze them.
- Track nextIndex in a shared write path so out-of-order writes fail fast on the sender.
When it happens
Trigger: Interleaving chunks from two concurrent chunked sends with different chunkIds; resending a chunk after a retry (duplicate index); sender recomputing count/byteLength mid-sequence; out-of-order delivery of chunk lines.
Common situations: Retrying a failed write without dropping decoder state; concurrent agent responses multiplexed on one stream; a buggy sender that re-serializes the frame after emitting early chunks.
Related errors
- rpc chunk sequence interrupted
- rpc chunk sequence must start at index 0
- 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/55665f9c7d1d344d.
Report an issue: GitHub.