can1357/oh-my-pi · error
rpc chunk sequence exceeds declared length
Error message
rpc chunk sequence exceeds declared length
What it means
As chunks accumulate, push tracks receivedBytes against the sequence's declared byteLength. This error is thrown as soon as accumulated chunk payload bytes exceed the declared total, proving the frame's byteLength header lied (or an extra oversized chunk slipped in) — caught before any full-payload allocation.
Source
Thrown at packages/coding-agent/src/modes/rpc/rpc-frame.ts:179
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,
streamedMessages?: readonly unknown[],
): object {
if (!isRecord(frame) || frame.type !== "agent_end" || !Array.isArray(frame.messages)) return frame;
let streamed = Number.isSafeInteger(streamedMessageCount)View on GitHub (pinned to 9690622007)
Solutions
- Compute byteLength with Buffer.byteLength(json, 'utf8'), never json.length.
- Ensure sum of per-chunk decoded byte counts equals byteLength exactly — no extra or oversized chunks.
- Compute byteLength from the same exact bytes that are sliced into chunks (serialize once, reuse the buffer).
Example fix
// before: character count, not bytes const byteLength = json.length; // after: UTF-8 byte length const byteLength = Buffer.byteLength(json, "utf8");
Defensive patterns
Strategy: validation
Validate before calling
// sender-side pre-flight: byteLength must be exact UTF-8 byte count
const bytes = Buffer.from(json, "utf8");
const byteLength = bytes.byteLength; // NOT json.length
let total = 0;
for (let i = 0; i < byteLength; i += 256 * 1024) {
total += Math.min(256 * 1024, byteLength - i);
}
if (total !== byteLength) throw new Error("chunk split does not sum to byteLength"); Try / catch
try {
const frame = decoder.push(parsedLine);
} catch (err) {
if (err instanceof Error && err.message === "rpc chunk sequence exceeds declared length") {
logger.error("sender byteLength header understates payload; discarding sequence");
decoder = new RpcFrameDecoder();
} else throw err;
} Prevention
- Always use Buffer.byteLength(json, 'utf8') for byteLength, never string .length.
- Serialize once and slice the same buffer you measure.
- Add a sender-side unit test with multi-byte UTF-8 payloads.
When it happens
Trigger: Sender declaring byteLength smaller than the actual UTF-8 size of the logical frame (e.g. using .length characters instead of Buffer.byteLength for multi-byte UTF-8); an extra chunk appended beyond count; oversized chunks that individually pass the 256KiB check but sum past the header.
Common situations: Hand-rolled senders measuring the JSON string with string length instead of byte length (CJK/emoji payloads inflate UTF-8 size); byteLength computed on the base64 form instead of raw bytes; duplicate chunk sends inflating receivedBytes.
Related errors
- invalid rpc chunk data
- rpc frame must be an object
- invalid rpc chunk metadata
- rpc chunk payload exceeds the transport limit
- RPC frame must be a JSON object
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/acc6b9862ba37402.
Report an issue: GitHub.