Skip to content

fix(server): fork Codex threads with active writers - #7414

Closed
f-trycua wants to merge 1 commit into
pingdotgg:mainfrom
trycua:t3code/fix-active-thread-writer
Closed

fix(server): fork Codex threads with active writers#7414
f-trycua wants to merge 1 commit into
pingdotgg:mainfrom
trycua:t3code/fix-active-thread-writer

Conversation

@f-trycua

@f-trycua f-trycua commented Aug 18, 2026

Copy link
Copy Markdown

Problem

Codex rejects thread/resume when another app-server process already owns the thread writer. T3 currently stops the session and surfaces the provider stack trace, even though Codex can branch the conversation safely.

Fix

Detect the specific active-writer response and call thread/fork with the requested working directory, model, service tier, approval policy, and sandbox mode. T3 then stores the forked thread ID and continues from the persisted conversation history. Missing-thread fallback and unrelated resume failures keep their existing behavior.

Tests

  • vp test run apps/server/src/provider/Layers/CodexSessionRuntime.test.ts
  • vp run --filter ./apps/server typecheck
  • targeted lint and format checks for both changed files

Model: gpt-5.6-sol
Harness: T3 Code Codex


Note

Medium Risk
Changes Codex session open/resume behavior on a specific provider error path; incorrect detection could fork when a fresh start was intended, but scope is narrow and covered by tests.

Overview
When thread/resume fails because another Codex app-server process already holds the thread writer, the server no longer surfaces a fatal error. It detects that case via isThreadActiveWriterError, logs a warning, and calls thread/fork with the session’s cwd, runtime mode (approval policy and sandbox), model, and optional service tier so the conversation can continue from persisted history under a new provider thread id.

Missing-thread and other recoverable resume failures still fall back to thread/start; unrelated resume errors are unchanged. Tests cover the detector, the resume→fork path, and existing fallback/propagation behavior.

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

Note

Fork Codex threads when thread/resume fails with an active writer error

  • Adds isThreadActiveWriterError predicate in CodexSessionRuntime.ts that detects errors containing both 'thread' and 'already has an active writer'.
  • When thread/resume fails with this error, openCodexThread now calls thread/fork instead of failing or starting a fresh thread, preserving thread continuity.
  • CodexThreadOpenResponse and CodexThreadOpenMethod types are extended to include thread/fork.

Macroscope summarized e884bb3.

Closes #8259

@coderabbitai

coderabbitai Bot commented Aug 18, 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: 8434e0b4-7e1a-4e2a-bb39-93e895cc8358

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

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.

❤️ Share

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

@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:M 30-99 changed lines (additions + deletions). labels Aug 18, 2026
@macroscopeapp

macroscopeapp Bot commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at e884bb3

Macroscope's review found this PR approvable — Straightforward bug fix adding error recovery for 'active writer' conflicts by forking threads instead of failing. Follows existing error handling patterns in the same file, has limited scope, and includes comprehensive test coverage.

You can add or adjust custom eligibility rules. Learn more.

@andybergon

Copy link
Copy Markdown

Hit this in the wild today on 0.0.34-nightly.20260824.1172 (macOS 26.6): every send to a Codex task failed with ProviderAdapterProcessError ... already has an active writer and the thread was stuck.

The other writer was ChatGPT Desktop's bundled app-server (26.818.41509, codex-cli 0.149.0-alpha.4.1). I had opened the T3-created thread in Desktop's thread list; lsof ~/.codex/thread-writer-locks/<id>.lock showed the Desktop process holding it. Closing the tab there didn't release it, quitting Desktop did. Upstream tracking is openai/codex#37403.

So the fork fallback here is the right call, since Desktop won't hand the lock back while it's running. One thing worth surfacing in the UI: after a fork the T3 task continues on a new thread id, so anything sent to the old thread from Desktop afterward won't appear in T3. A short note in the chat that the thread was forked because another app owned it would make that divergence visible instead of silent.

@ElliotDrel

Copy link
Copy Markdown

Hitting this today on the current stable Windows build, multi-account Codex setup (shared CODEX_HOME + shadow home for a second account). Switching accounts mid-thread reliably throws:

ProviderAdapterProcessError: Provider adapter process error (codex) for thread <redacted>: thread <redacted> already has an active writer

Matches the fix described here exactly — the first account's app-server process is still holding the writer lock when the second account's process tries thread/resume on the same thread. Would love to see this merged; right now the only workaround is avoiding mid-thread account switches or manually disabling the first provider to force its process to exit and release the lock.

+1 for merging.

@t3-code

t3-code Bot commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

closing this version as part of a pr cleanup at the request of @StiensWout.

automatically forking on an active-writer conflict changes the native conversation identity without a user-facing explanation. recovery is useful, but the fork and resulting divergence should be explicit to the user, with a recovery choice where appropriate, rather than only recorded in a server log.

thanks for the contribution. if you disagree with this decision, you are welcome to open a new pr, link back to this one, and explain how your proposal addresses these concerns or why a different approach is warranted.

@t3-code t3-code Bot closed this Sep 8, 2026
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:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Switching Codex provider instances can leave a thread stuck on "already has an active writer"

3 participants