fix(cli): ensure store directory exists in createFileWithStore (#4286) - #4966
kaiizer777 wants to merge 1 commit into
Conversation
🦋 Changeset detectedLatest commit: 8f4da02 The changes in this PR will be included in the next version bump. This PR includes changesets to release 27 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
Hi @kaiizer777, thanks for your interest in contributing! This project requires that pull request authors are vouched, and you are not in the list of vouched users. This PR will be closed automatically. See https://github.com/triggerdotdev/trigger.dev/blob/main/CONTRIBUTING.md for more details. |
|
Vouch request is open at #4963. Ready for review once vouched! |
|
Note Currently processing new changes in this PR. This may take a few minutes, please wait... ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Advanced Run ID: 📒 Files selected for processing (3)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
|
||
| // Ensure build directory exists | ||
| // Ensure build directory and store directory exist | ||
| await fsModule.mkdir(storeDir, { recursive: true }); |
There was a problem hiding this comment.
🟡 Concurrent cleanup still deletes store
When the previous session cleans up after mkdir, createFileWithStore still reaches a missing store. The new dev session's build still crashes during handover.
Learn more
The store is shared by dev sessions for the same project and branch. Each session registers an exit callback that recursively removes that shared directory in getStoreDir. Creating it once at the start of this function does not establish ownership or synchronize with that callback. The old callback can run immediately after mkdir, after the existence check, or after the store write. A later store operation then raises ENOENT, preserving the original handover failure.
Example: Session B executes mkdir(storeDir) and pauses. Session A exits and recursively removes storeDir. Session B then executes writeFile(storePath, contents) and receives ENOENT instead of completing its rebuild.
Recommended fix: Stop an exiting session from deleting a store that another session uses. Give stores session-specific ownership, coordinate shared cleanup with a lock or reference count, or retain the shared store and clean stale data only when no session can use it. Add a handover test that deletes the store after createFileWithStore begins.
Was this helpful? React with 👍 or 👎 to provide feedback.
| "trigger.dev": patch | ||
| --- | ||
|
|
||
| Ensure store directory exists before writing in createFileWithStore to prevent ENOENT crashes during dev session handover. |
Resolves #4286
Root Cause
In
packages/cli-v3/src/utilities/tempDirectories.ts,getStoreDir()creates.trigger/tmp/storewhen a dev session starts and registers an exit cleanup handler that deletes it recursively.When a developer starts a second
trigger devsession for the same project, the previous dev session exits and its cleanup handler wipes out.trigger/tmp/storeout from under the new session.In
packages/cli-v3/src/utilities/fileSystem.ts,createFileWithStore()ensured the build destination directory exists viaawait fsModule.mkdir(pathModule.dirname(filePath), { recursive: true });, but never ensuredstoreDirexists before writing the hashed artifact viaawait fsModule.writeFile(storePath, contents);.When
storeDirhas been deleted by the exiting session,createFileWithStore()threw an unhandledENOENT: no such file or directory, crashing the build or causing watch rebuilds to stall.Changes
packages/cli-v3/src/utilities/fileSystem.ts, addedawait fsModule.mkdir(storeDir, { recursive: true });insidecreateFileWithStore()alongside the destination directory check.packages/cli-v3/src/utilities/fileSystem.test.tsverifying that:createFileWithStore()succeeds whenstoreDirdoes not exist yet (creates it and writes file).storeDirexists uses content-addressable caching (hardlink or copy)./and+characters are properly sanitized.trigger.dev.Note
A vouch request for CI/contributions is open at #4963.