Skip to content

fix(streaming): handle boundary-not-found in multipart stream transformers#1709

Open
ankit25bcs10610 wants to merge 1 commit into
Portkey-AI:mainfrom
ankit25bcs10610:fix/stream-multipart-boundary-index
Open

fix(streaming): handle boundary-not-found in multipart stream transformers#1709
ankit25bcs10610 wants to merge 1 commit into
Portkey-AI:mainfrom
ankit25bcs10610:fix/stream-multipart-boundary-index

Conversation

@ankit25bcs10610

Copy link
Copy Markdown

What

In getFormdataToFormdataStreamTransformer and formDataToOctetStreamTransformer:

const boundaryIndex = buffer.indexOf(boundary);
const safeLength = boundaryIndex ?? buffer.length;
const content = buffer.slice(0, safeLength);

String.prototype.indexOf returns -1 when the boundary isn't found. -1 is not nullish, so ?? buffer.length never triggers and safeLength becomes -1.

When a file chunk arrives before its closing boundary — the normal case for large uploads streamed across multiple reads — this means:

  • buffer.slice(0, -1) emits the content minus its last byte, and
  • the non-file branch does buffer = buffer.slice(-1), discarding almost the entire buffer.

The result is corrupted chunked file uploads.

Fix

Only fall back to buffer.length when the boundary is genuinely absent:

const safeLength = boundaryIndex === -1 ? buffer.length : boundaryIndex;

Applied at both sites. npm run format:check passes.

Note: these transformers operate on a ReadableStream/TransformStream pipeline, so I did not add a unit test (would require standing up the full stream harness). Happy to add one if you'd prefer — the change itself is a self-contained correctness fix.

`buffer.indexOf(boundary)` returns `-1` when the boundary is not in the
current buffer, but `-1` is not nullish, so `boundaryIndex ?? buffer.length`
never falls back — `safeLength` becomes `-1`.

When a file chunk arrives before its closing boundary (the normal case for
large uploads spanning multiple reads), `buffer.slice(0, -1)` drops the
last byte from the emitted content and the non-file branch
`buffer.slice(-1)` discards almost the entire buffer, corrupting chunked
uploads in getFormdataToFormdataStreamTransformer and
formDataToOctetStreamTransformer.

Fall back to buffer.length only when the boundary is absent
(`boundaryIndex === -1`).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant