Bun 1.4.3 fetch stream errors: catch a cut-off Sume video download
Bun 1.4.3 fixes response streams that ended cleanly after a transfer failure. Still check the byte count when you save a finished Sume video to disk.

Bun 1.4.3 (October 10, 2026) fixes cases where a fetch response stream ended cleanly after the transfer had actually failed. If you save a finished Sume video with Bun.write(path, response), upgrade, then add one more check anyway: compare the bytes you wrote with the Content-Length header when the server sent one, and re-download on a mismatch.
The fix is listed in the Bun v1.4.3 release notes (read 2026-10-13) next to related items: native readers now receive signal.reason instead of a generic AbortError when a body is aborted, and a cloned response body rejects on stream failure instead of just ending. The job and result side is covered in Jobs and results.
What Bun fixed
Before 1.4.3, a consumer reading the stream could see a normal end of data when the connection broke mid-body. For a small JSON reply that is a parse error you notice. For a multi-megabyte clip it is a file that plays for a few seconds and stops.
| Release-note item | Effect on a download script |
|---|---|
| Stream ended cleanly instead of rejecting after a transfer failure | A broken transfer now rejects; your catch runs |
| Aborted body gave a generic AbortError | You now get signal.reason, such as a TimeoutError |
| Cloned response body ended instead of rejecting | tee-style reads also fail loudly |
Why a size check still belongs in the script
A fixed runtime narrows the gap, not every gap: a proxy or CDN can close a response early with a status you cannot tell from success, and servers that stream without a length give you nothing to compare. A size check costs one stat call.
Separate that from the job itself. A finished Sume job is durable, so a bad download is never a reason to resubmit generation. Per Jobs and results, store the job id and read the result again; resubmitting would start a new billed job.
Save, verify, retry the read
This helper takes a URL you already read from a completed job's result, writes it, and retries only the download.
async function save(url: string, path: string) {
for (let attempt = 0; attempt < 3; attempt++) {
try {
const res = await fetch(url, { signal: AbortSignal.timeout(120_000) });
if (!res.ok) throw new Error(`download ${res.status}`);
const expected = Number(res.headers.get("content-length") ?? NaN);
const written = await Bun.write(path, res);
if (!Number.isNaN(expected) && written !== expected) {
throw new Error(`short file: ${written} of ${expected}`);
}
return written;
} catch (err) {
if (attempt === 2) throw err;
await Bun.sleep(2 ** attempt * 1000);
}
}
}Checklist
Keep generation and download as separate steps, so each has its own retry rule.
- Retry the download, not the Sume submit.
- Reread the result from the job id if the link no longer works.
- Log
err.causeor the abort reason; 1.4.3 now carries it through. - Delete the partial file before the next attempt.
Sources
Related posts
More in Developers
- Extend a Grok Imagine video on Sume: chain by last frame
xAI's guide lists video extension from the final frame. Sume's Grok row has no extend, so pull a late frame with video-frames and start the next clip from it.
- Claude Code 2.1.296: MCP tool names over 128 characters, and Sume's
Claude Code 2.1.296 leaves out an MCP tool whose name exceeds 128 characters. The longest tool name in Sume's hosted list is 28, so none are near it.
- Claude Code subagent autoCompactWindow: keep Sume job ids
Claude Code 2.1.296 lets a subagent auto-compact earlier than the main chat. Keep Sume job ids out of the summary and re-read state with jobs_status.
- CLAUDE_CODE_WORKFLOW_SUBAGENT_MODEL: model choice vs Sume spend gates
Claude Code 2.1.296 can run every workflow agent on one model. Sume's idempotency_key, dry_run and max_spend_credits gates do not change with the model.
Written by Sume