Skip to content

fix: skip writes to destroyed file streams - #1115

Open
neallin917 wants to merge 1 commit into
node-formidable:masterfrom
neallin917:codex/skip-writes-to-destroyed-files
Open

fix: skip writes to destroyed file streams#1115
neallin917 wants to merge 1 commit into
node-formidable:masterfrom
neallin917:codex/skip-writes-to-destroyed-files

Conversation

@neallin917

@neallin917 neallin917 commented Jul 29, 2026

Copy link
Copy Markdown

Summary

  • skip writes when a persistent file stream has already been destroyed
  • align PersistentFile.write() with the existing VolatileFile.write() guard
  • add a deterministic regression test for the destroyed-but-not-yet-closed stream state

Why

A destroyed fs.WriteStream is not necessarily marked closed immediately. During that interval, PersistentFile.write() currently calls .write() and records the buffer as successfully written even though the stream has already been destroyed. Depending on timing and the underlying filesystem callback, this is also the race behind Cannot call write after a stream was destroyed failures reported after aborted uploads.

The new test demonstrates the exact state before the fix: destroyed === true, closed === false, and the ignored buffer was still added to file.size.

This addresses the destroyed-stream race discussed in #958 without claiming to reproduce every environment-specific crash from that report.

Validation

  • pnpm test: 12 node:test tests passed; 91 Jest tests passed and 3 existing tests skipped
  • pnpm exec prettier --check src/PersistentFile.js test-node/files/persistent-file.test.js
  • pnpm exec eslint --no-cache --quiet --format codeframe src/PersistentFile.js test-node/files/persistent-file.test.js
  • pnpm run build-package
  • git diff --check

Greptile Summary

Fixes a race in persistent upload-file handling.

  • Skips writes when the underlying persistent file stream is already destroyed, matching the existing closed-stream behavior.
  • Adds a deterministic regression test confirming ignored writes do not increase the file size.

Confidence Score: 4/5

The hash-accounting defect should be fixed before merging because destroyed-stream writes can produce metadata that does not match persisted content.

The new early return prevents disk writes and size updates, but it occurs after the hash is updated, so a subsequently finalized upload can expose a digest containing ignored bytes.

Files Needing Attention: src/PersistentFile.js

Important Files Changed

Filename Overview
src/PersistentFile.js Adds the destroyed-stream guard, but ignored buffers are still incorporated into configured content hashes.
test-node/files/persistent-file.test.js Covers size accounting for destroyed streams but does not exercise hash accounting.

Comments Outside Diff (1)

  1. src/PersistentFile.js, line 63-71 (link)

    P1 Ignored writes still alter hashes

    When a hashed upload writes after its stream has been destroyed, hash.update() includes the ignored buffer before this guard returns; if the part subsequently ends, the emitted file hash includes bytes that were never persisted, causing integrity checks against the file contents to fail.

    Fix in Codex Fix in Claude Code

Fix All in Codex Fix All in Claude Code

Reviews (1): Last reviewed commit: "fix: skip writes to destroyed file strea..." | Re-trigger Greptile

@neallin917
neallin917 marked this pull request as ready for review July 29, 2026 05:12
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