can1357/oh-my-pi · error
Invalid chunk size: ${sizeLine}
Error message
Invalid chunk size: ${sizeLine} What it means
parseChunkedBody decodes HTTP chunked-transfer-encoding bodies streamed through the local MITM proxy. Before reading each chunk it parses the hex size line; if the line is not a valid non-negative safe hex integer (e.g. because stream framing desynced or the server sent a malformed/truncated size line), it throws this error instead of producing garbage body bytes.
Source
Thrown at packages/coding-agent/src/cli/claude-trace-cli.ts:243
}
function responseHasNoBody(statusCode: number | undefined): boolean {
if (statusCode === undefined) return false;
return (statusCode >= 100 && statusCode < 200) || statusCode === 204 || statusCode === 304;
}
function parseChunkedBody(buffer: Buffer): ChunkedParseResult {
let offset = 0;
const chunks: Buffer[] = [];
while (true) {
const lineEnd = buffer.indexOf(CRLF, offset);
if (lineEnd < 0) return { complete: false, consumed: 0, body: Buffer.alloc(0) };
const sizeLine = buffer.subarray(offset, lineEnd).toString("latin1");
const semicolon = sizeLine.indexOf(";");
const sizeText = (semicolon >= 0 ? sizeLine.slice(0, semicolon) : sizeLine).trim();
const size = Number.parseInt(sizeText, 16);
if (!Number.isSafeInteger(size) || size < 0) {
throw new Error(`Invalid chunk size: ${sizeLine}`);
}
const dataStart = lineEnd + CRLF.length;
if (size === 0) {
if (buffer.length < dataStart + CRLF.length) return { complete: false, consumed: 0, body: Buffer.alloc(0) };
if (buffer.subarray(dataStart, dataStart + CRLF.length).equals(CRLF)) {
return { complete: true, consumed: dataStart + CRLF.length, body: Buffer.concat(chunks) };
}
const trailerEnd = buffer.indexOf(DOUBLE_CRLF, dataStart);
if (trailerEnd < 0) return { complete: false, consumed: 0, body: Buffer.alloc(0) };
return { complete: true, consumed: trailerEnd + DOUBLE_CRLF.length, body: Buffer.concat(chunks) };
}
const chunkEnd = dataStart + size;
if (buffer.length < chunkEnd + CRLF.length) return { complete: false, consumed: 0, body: Buffer.alloc(0) };
chunks.push(buffer.subarray(dataStart, chunkEnd));
offset = chunkEnd + CRLF.length;
}
}
View on GitHub (pinned to 9690622007)
Solutions
- Restart the trace so the proxy captures the connection from the beginning (full chunk sequence from the first byte).
- Check the upstream for intermediaries (corporate proxies, antivirus TLS inspection) that may mangle chunked framing and bypass them.
- If the endpoint truly doesn't use chunked encoding, ensure the capture path doesn't assume Transfer-Encoding: chunked for that response.
- Log the offending sizeLine (it's embedded in the message) to identify desync and fix the stream-offset bookkeeping.
Example fix
// before: attaching capture mid-stream and feeding arbitrary bytes parseChunkedBody(buffer.slice(randomOffset), chunks); // after: only feed bytes from a tracked stream offset let offset = 0; // advance only by `consumed` returned from parseChunkedBody parseChunkedBody(buffer.subarray(offset), chunks); offset += consumed;
Defensive patterns
Strategy: try-catch
Try / catch
try {
const parsed = parseChunkedBody(buffer.subarray(offset), chunks);
} catch (err) {
if (err instanceof Error && err.message.startsWith("Invalid chunk size")) {
// log err.message (contains raw size line), reset stream offset, re-sync or abort capture
} else throw err;
} Prevention
- Feed bytes to the parser only from a monotonically tracked offset advanced by `consumed`
- Capture the connection from its first byte — never attach mid-stream
- Keep a raw fallback dump of the response so a desync can be diagnosed offline
When it happens
Trigger: The buffered bytes between CRLF markers are not parseable as a hex chunk size — e.g. the proxy captured mid-stream (joined an existing connection past a chunk boundary), the upstream server sent a malformed chunked response, or binary/deflated bytes shifted the framing so a size line contains non-hex characters.
Common situations: Tracing a Claude Code session where the capture attaches after the response already started; an upstream proxy (corporate proxy, VPN) rewriting chunked responses; a server sending non-chunked data mislabeled with Transfer-Encoding: chunked.
Related errors
- MCP SSE resume returned unsupported Content-Type: ${contentT
- Failed to parse top stories
- Failed to parse new stories
- Failed to parse best stories
- proxy returned malformed workflow run payload
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/6a3bff8d6f41993c.
Report an issue: GitHub.