Skip to content

fix(server): stop tying codex text-generation temp files to the caller's scope - #5406

Merged
juliusmarminge merged 2 commits into
t3code/codex-turn-mappingfrom
t3code/codex-textgen-temp-scope
Aug 5, 2026
Merged

fix(server): stop tying codex text-generation temp files to the caller's scope#5406
juliusmarminge merged 2 commits into
t3code/codex-turn-mappingfrom
t3code/codex-textgen-temp-scope

Conversation

@juliusmarminge

@juliusmarminge juliusmarminge commented Aug 5, 2026

Copy link
Copy Markdown
Member

Stacked on #2829. Follow-up to #5309 — explains and fixes why branch renaming still didn't work in real builds even though #5309's rename path executed.

Diagnosis (from a live Alpha build containing #5176 + #5309)

Titles generated fine, branches stayed t3code/<hash>. Traces showed the rename fork running and failing in 22ms:

TextGenerationError: Text generation failed in generateBranchName: Failed to write temp file
  [cause]: ENOENT: no such file or directory, open '/var/folders/.../T/t3code-codex-schema-10580-Ahg5y9/a30ebec4bc02'

runCodexJson writes its --output-schema / --output-last-message temp files with makeTempFileScoped, whose Scope requirement leaks to the ambient fiber context (swallowed by the generic S["DecodingServices"] in the return annotation, so it never typechecked as missing). The branch rename fork inherits its context from the launchThread RPC request, whose scope has long since closed by the time the fork runs — and registering a finalizer on a closed scope runs it immediately, deleting the temp directory between creation and write. Hence ENOENT on every branch generation, with #5309's deliberate fallback keeping the temp name.

Title generation kept working because #5176 runs it on the durable effect worker, whose ambient scope stays live — which is exactly why the symptom split (titles ✓ / branches ✗).

Fix

Use unscoped makeTempFile and remove the per-file temp directories in runCodexJson's existing explicit Effect.ensuring(cleanup) instead. Generation is now self-contained regardless of which fiber calls it, and the temp directories (previously left behind by the file-only unlink whenever the scope path wasn't exercised) are cleaned up too.

Testing

  • New regression test: generateBranchName succeeds with an explicitly closed ambient Scope provided — fails with the ENOENT error before the fix, passes after.
  • Full CodexTextGeneration suite: 18 passed.
  • Typecheck clean for t3.

🤖 Generated with Claude Code


Note

Medium Risk
Changes temp-file lifecycle for all Codex JSON generation paths; behavior is intentional but touches shared CLI orchestration used by commits, PRs, branches, and titles.

Overview
Fixes background generateBranchName failures (ENOENT on temp files) when Codex CLI schema/output temps were created via makeTempFileScoped, so a closed ambient Scope from the launching RPC could reap the directory before the write finished.

writeTempFile now uses unscoped makeTempFile with explicit cleanup: removeTempFileDir on write failure, and runCodexJson’s existing Effect.ensuring removes the full temp directories (not single-file unlinks) on success or failure.

Adds a regression test that generateBranchName succeeds when Scope.Scope is already closed.

Reviewed by Cursor Bugbot for commit 0a5b8c1. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Fix codex text-generation temp files to be independent of the caller's scope

  • writeTempFile in CodexTextGeneration.ts switches from makeTempFileScoped to makeTempFile, removing the dependency on an ambient Scope being open.
  • A new removeTempFileDir helper cleans up the entire temp directory (recursively) on both success and error paths, replacing per-file unlinks that could leave directories behind.
  • If output temp file creation fails, the schema temp directory is now explicitly removed to prevent leakage.
  • A regression test verifies that generateBranchName works correctly even when the ambient scope is already closed.

Macroscope summarized 0a5b8c1.

…r's scope

runCodexJson wrote its schema and output temp files with
makeTempFileScoped, leaking a Scope requirement to the ambient fiber
context. When generation runs from a background fiber whose launching
request scope has already closed — the v2 worktree branch rename fork —
the finalizer registered on the closed scope fires immediately, reaping
the temp directory between creation and write. Every branch name
generation then failed with ENOENT ("Failed to write temp file") and
threads kept their temporary t3code/<hash> branches, while title
generation kept working because the durable effect worker's scope stays
live.

Use unscoped makeTempFile and remove the per-file temp directories in
runCodexJson's existing explicit cleanup instead, so generation is
self-contained no matter which fiber calls it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 211bf859-5a51-4ff3-9b3c-a1cb8563dbb6

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:S 10-29 changed lines (additions + deletions). labels Aug 5, 2026
Comment thread apps/server/src/textGeneration/CodexTextGeneration.ts Outdated
…rtway

Review follow-up: with the temp files no longer scope-managed, a failure
between allocations leaked what was already created — the schema temp
directory survived if its own write failed or if the output allocation
failed, since Effect.ensuring(cleanup) is only installed after both
exist. Each allocation now removes its own directory on failure, and the
output allocation removes the schema directory on the way out.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@github-actions github-actions Bot added size:M 30-99 changed lines (additions + deletions). and removed size:S 10-29 changed lines (additions + deletions). labels Aug 5, 2026
@macroscopeapp

macroscopeapp Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved 0a5b8c1

Straightforward bug fix changing temp file management from scope-based to manual cleanup, addressing an issue where background fibers outlive their launching scope. The author is the primary contributor to this code, and the fix includes a test case.

You can customize Macroscope's approvability policy. Learn more.

@juliusmarminge
juliusmarminge merged commit e246599 into t3code/codex-turn-mapping Aug 5, 2026
17 checks passed
@juliusmarminge
juliusmarminge deleted the t3code/codex-textgen-temp-scope branch August 5, 2026 12:52
juliusmarminge added a commit that referenced this pull request Aug 5, 2026
…r's scope (#5406)

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:M 30-99 changed lines (additions + deletions). vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant