{"record":{"id":"4b7ddc273613487a","repo":"can1357/oh-my-pi","slug":"rpc-chunk-payload-exceeds-the-transport-limit","errorCode":null,"errorMessage":"rpc chunk payload exceeds the transport limit","messagePattern":"rpc chunk payload exceeds the transport limit","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/modes/rpc/rpc-frame.ts","lineNumber":162,"sourceCode":"\t\t}\n\t\tconst { chunkId, index, count, byteLength } = value;\n\t\tif (\n\t\t\ttypeof chunkId !== \"string\" ||\n\t\t\tchunkId.length === 0 ||\n\t\t\tchunkId.length > 128 ||\n\t\t\t!Number.isSafeInteger(index) ||\n\t\t\t!Number.isSafeInteger(count) ||\n\t\t\t!Number.isSafeInteger(byteLength) ||\n\t\t\tindex < 0 ||\n\t\t\tcount < 2 ||\n\t\t\tcount > Math.ceil(MAX_RPC_REASSEMBLED_BYTES / RPC_CHUNK_PAYLOAD_BYTES) ||\n\t\t\tindex >= count ||\n\t\t\tbyteLength < MAX_RPC_FRAME_BYTES ||\n\t\t\tbyteLength > MAX_RPC_REASSEMBLED_BYTES\n\t\t)\n\t\t\tthrow new Error(\"invalid rpc chunk metadata\");\n\t\tconst bytes = decodeBase64(value.data);\n\t\tif (bytes.byteLength > RPC_CHUNK_PAYLOAD_BYTES) throw new Error(\"rpc chunk payload exceeds the transport limit\");\n\n\t\tif (!this.#pending) {\n\t\t\tif (index !== 0) throw new Error(\"rpc chunk sequence must start at index 0\");\n\t\t\tthis.#pending = { chunkId, count, byteLength, nextIndex: 0, chunks: [], receivedBytes: 0 };\n\t\t}\n\t\tconst pending = this.#pending;\n\t\tif (\n\t\t\tpending.chunkId !== chunkId ||\n\t\t\tpending.count !== count ||\n\t\t\tpending.byteLength !== byteLength ||\n\t\t\tpending.nextIndex !== index\n\t\t)\n\t\t\tthrow new Error(\"rpc chunk sequence mismatch\");\n\t\tpending.chunks.push(bytes);\n\t\tpending.receivedBytes += bytes.byteLength;\n\t\tpending.nextIndex++;\n\t\tif (pending.receivedBytes > pending.byteLength) throw new Error(\"rpc chunk sequence exceeds declared length\");\n\t\tif (pending.nextIndex < pending.count) return undefined;","sourceCodeStart":144,"sourceCodeEnd":180,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/modes/rpc/rpc-frame.ts#L144-L180","documentation":"After base64 decoding a chunk's payload, push verifies the decoded bytes do not exceed RPC_CHUNK_PAYLOAD_BYTES (256 KiB). This error is thrown when a single chunk carries more payload than one slice is allowed to hold, breaking the sender/receiver size contract even though the whole-frame ceiling might still be respected.","triggerScenarios":"A sender slicing the logical frame into pieces larger than 256 KiB (e.g. using a different chunk size constant); sending the entire frame as one chunk with count≥2 metadata; encoding overhead miscounted so decoded bytes exceed the slice size.","commonSituations":"Third-party implementations of protocol v2 that picked a bigger chunk size; constants changed independently on sender and receiver sides; confusion between base64 character count and decoded byte count.","solutions":["Slice the UTF-8 bytes in 256*1024-byte pieces: bytes.subarray(i*262144, (i+1)*262144).","Match the receiver's RPC_CHUNK_PAYLOAD_BYTES constant exactly — do not invent a larger chunk size.","Assert per-chunk decoded length ≤ 262144 on the sender before writing the line."],"exampleFix":"// before: 1MiB slices\nconst slice = bytes.subarray(index * 1024 * 1024, (index + 1) * 1024 * 1024);\n// after: 256KiB slices\nconst slice = bytes.subarray(index * 256 * 1024, (index + 1) * 256 * 1024);","handlingStrategy":"validation","validationCode":"const CHUNK = 256 * 1024;\n// pre-send check per chunk\nif (chunkBuffer.byteLength > CHUNK) throw new Error(`chunk too large: ${chunkBuffer.byteLength} > ${CHUNK}`);","typeGuard":null,"tryCatchPattern":"try {\n  decoder.push(parsedLine);\n} catch (err) {\n  if (err instanceof Error && err.message === \"rpc chunk payload exceeds the transport limit\") {\n    logger.error(\"sender chunk size exceeds 256KiB; align sender with receiver constants\");\n  } else throw err;\n}","preventionTips":["Slice payloads in 256*1024-byte pieces exactly as encodeChunkedRpcFrames does.","Never change the chunk size on one side only.","Assert decoded (not base64) byte length in sender-side tests."],"tags":["rpc","protocol","frame-size","validation"],"backgroundTag":"rpc-chunk-size-limit-exceeded","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}