Follow-up from #6. Pre-existing edge case found
while reviewing that PR — not caused by the shared-budget change.
Scope
During bounded PNG decompression, a budget refusal attempts reader.cancel() before
rethrowing:
try { onBytes?.(value.length); }
catch (error) { await reader.cancel(); throw error; }
If cancel() itself rejects, that rejection replaces the original MalformedFileError.
The surrounding handler only re-throws MalformedFileError and turns everything else into
{ status: 'unreadable' } — so a refusal would be degraded to "this text could not be
decoded", which for text chunks means the file is reported and accepted rather than
refused. The same shape exists on the overflow path, which has carried it since before the
budget work.
Runtime likelihood is low: ReadableStreamDefaultReader.cancel() normally settles. The
severity is not about likelihood — this sits directly on the fail-closed boundary, where a
cleanup failure must never decide the verdict.
Done when
- the original budget/refusal error always wins over a cleanup failure;
- stream cancellation stays best-effort — a failing cancel is not itself a refusal reason;
- a rejecting
reader.cancel() cannot turn a fail-closed condition into acceptance;
- a regression test proves the path, not just the intent;
- no broader stream abstraction refactor unless evidence requires one.
Severity
P1 trust hygiene.
🤖 Generated with Claude Code
Follow-up from #6. Pre-existing edge case found
while reviewing that PR — not caused by the shared-budget change.
Scope
During bounded PNG decompression, a budget refusal attempts
reader.cancel()beforerethrowing:
If
cancel()itself rejects, that rejection replaces the originalMalformedFileError.The surrounding handler only re-throws
MalformedFileErrorand turns everything else into{ status: 'unreadable' }— so a refusal would be degraded to "this text could not bedecoded", which for text chunks means the file is reported and accepted rather than
refused. The same shape exists on the overflow path, which has carried it since before the
budget work.
Runtime likelihood is low:
ReadableStreamDefaultReader.cancel()normally settles. Theseverity is not about likelihood — this sits directly on the fail-closed boundary, where a
cleanup failure must never decide the verdict.
Done when
reader.cancel()cannot turn a fail-closed condition into acceptance;Severity
P1 trust hygiene.
🤖 Generated with Claude Code