openai / openai/codex

app-server: client-supplied thread id on thread/start and thread/fork, so a timed-out create is recoverable

Open
#41,887 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

app-server CLI enhancement
Dominant language
Rust
Stars
125k
Forks
19.4k
PR merge metrics
PR metrics pending

Description

What variant of Codex are you using?

CLI / app-server (codex-cli 0.151.0, macOS), driven programmatically over the app-server JSON-RPC API.

What feature would you like to see?

Please add a client-supplied identity field to thread/start and thread/fork — a clientThreadId (or idempotencyKey), mirroring the clientUserMessageId that TurnStartParams already accepts.

Why: a timed-out thread/start is unrecoverable for the client.

The app-server has no transport-level cancellation — nothing addresses "request N" — which is a reasonable design, because every cancellable thing is a named object with its own stop verb (turn/interrupt, command/exec/terminate, process/kill). But that name arrives in the response the client is still waiting for. When a request outlives its deadline, the client is left with no handle at all.

For turns this is survivable: thread/turns/list reports the thread's inProgress turn, so a client can recover the id and interrupt it. I verified this against a real app-server — recovering the id of a turn whose turn/start response I deliberately ignored, then interrupting by that recovered id, and confirming the id matched what turn/start eventually returned.

Thread creation has no equivalent. If thread/start times out, the thread may or may not exist, it has no id the client knows, and there is no way to ask "did the thread I asked for get created?" The client's only options are:

  1. Retry, and risk creating a second thread (this is what #36257 reports — one logical create replayed into seven thread/start requests).
  2. Give up, and leak a thread that may be running unattended.
  3. Watch the abandoned request id and reconcile if the response ever arrives — which only helps when it does arrive.

A caller-supplied id collapses all three. The client already knows the identity it asked for, so a retry is safe, a duplicate is detectable server-side, and "did this land?" becomes answerable.

Why this level rather than a cancel verb. A generic $/cancelRequest would let the server drop the in-flight future, but dropping a future does not un-create a thread. Identity is the thing that actually fixes the failure, and it's a smaller change: one optional field on two *Params structs, following the client_user_message_id precedent in app-server-protocol/src/protocol/v2/turn.rs.

Additional information

Related, none of which cover thread/start itself:

  • #36257 — Android Remote replays one create_thread operation into seven thread/start requests. Same failure, different client.
  • #36250 — asks for an idempotencyKey, but on the Desktop-owned create_thread tool rather than the protocol method. Solving it at the app-server level would cover Desktop and every other client at once.
  • #30348 — thread/start timeouts in Desktop.

Reported from an independent MCP client that orchestrates concurrent app-server workers, so this is not Desktop-specific. Happy to send a PR if the shape above is one you'd take — the clientUserMessageId precedent makes it fairly mechanical.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in app-server-protocol/src/protocol/v2/turn.rs to review the client_user_message_id precedent, then locate the parameter definitions and handling for thread/start and thread/fork. Confirm both methods accept the optional client-supplied identity and that retries can identify an existing creation without changing current behavior; finish by running the relevant app-server protocol tests.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
api
Issue type
Feature
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
66/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.