[ChatGPT Work] Read-only tool calls can remain pending after manual stop without a terminal cancellation receipt
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 125k
- Forks
- 19.4k
- PR merge metrics
- PR metrics pending
Description
Summary
Two consecutive read-only tool operations in ChatGPT Work remained pending until the user manually stopped them:
- A GitHub inspection through the browser remained pending until manually stopped at 07:44 Europe/Zurich.
- The immediately following continuity-skill read remained pending for approximately 42 minutes until manually stopped at 08:28 Europe/Zurich.
The second incident occurred in a different read-only capability after the browser inspection had been stopped. This suggests a tool-runtime, orchestration or cancellation failure rather than only a GitHub page-rendering problem, but the available evidence does not establish the internal root cause.
Neither operation intended an external mutation. No GitHub mutation, upstream comment, account action or other external side effect was observed.
Environment
- ChatGPT Work Mode
- Long-running, tool-heavy governance conversation
- First affected operation: read-only GitHub inspection through the browser
- Second affected operation: read-only continuity-skill retrieval
- No external mutation requested
- Observed on 30 August 2026
The report intentionally avoids inferring the internal tool bridge, runtime process, cancellation transport or browser implementation involved.
Steps that produced the incident
- Request a read-only inspection of GitHub state through the browser.
- Observe that the operation remains pending instead of returning a result, structured error or timeout.
- Manually stop the pending operation at 07:44 Europe/Zurich.
- Start the next read-only operation, a continuity-skill read.
- Observe that the second capability also remains pending.
- Wait approximately 42 minutes without a terminal result.
- Manually stop the second operation at 08:28 Europe/Zurich.
- Observe that the conversation exposes no durable terminal receipt confirming whether either underlying operation completed, failed, timed out, cancelled or remained active.
Actual result
- Both read-only operations could remain pending without a bounded terminal outcome.
- Manual stop returned control to the conversation but did not provide an authoritative cancellation acknowledgement.
- The user could not determine whether the underlying work had actually terminated.
- A successor capability encountered the same pending behavior even though it was not a browser or GitHub rendering operation.
- The visible state did not distinguish:
- completed but response not delivered;
- failed without a delivered error;
- timed out;
- cancellation requested but not acknowledged;
- cancelled;
- still running.
- Continuing recovery risked creating overlapping calls and obscuring the original execution state.
The incidents demonstrate an observability and recovery gap. They do not prove that the first operation caused the second or identify which runtime layer failed.
Expected result
Every tool operation should have an end-to-end lifecycle that remains observable independently of assistant-response delivery.
For an ordinary read-only call, the product should:
- apply a documented execution deadline;
- expose a stable operation identifier;
- return one authoritative state: completed, failed, timed out, cancelled or indeterminate;
- propagate cancellation through every active orchestration and tool layer;
- acknowledge cancellation only when the underlying operation has actually terminated;
- retain a durable terminal or indeterminate receipt across reconnects and replacement conversations;
- prevent silent retry or overlapping fallback while a prior operation remains indeterminate.
If cancellation cannot be confirmed, the product should say indeterminate rather than imply that the visible stop terminated the underlying work.
User impact
- A nominally read-only task can occupy a conversation indefinitely.
- The user cannot tell whether it is safe to retry, switch tools or start a successor operation.
- Manual stop may appear effective without proving underlying termination.
- Recovery attempts can overlap, compound resource use and obscure which call is still active.
- Site-specific diagnosis becomes unreliable when the next unrelated capability also hangs.
- Read-only calls have low external-side-effect risk, but the same missing lifecycle contract would be more dangerous around mutating actions.
- Replacement conversations cannot recover execution state from a durable receipt.
Requested product behavior
- Assign every tool call a stable operation ID and lifecycle record.
- Apply an end-to-end deadline that covers the outer orchestration wait and the underlying tool execution.
- Propagate cancellation to browser controllers, connectors, skills, MCP servers and other active capability layers.
- Record cancellation requested and cancellation acknowledged as separate states.
- Return a durable receipt with:
- operation ID;
- capability and privacy-minimized target;
- start time and deadline;
- completion, failure, timeout or cancellation time;
- final state;
- whether underlying termination was acknowledged.
- Show indeterminate when the product cannot establish a terminal state.
- Let the current or a replacement conversation inspect outstanding and recent operation receipts.
- Warn or block when a retry would overlap an indeterminate operation.
- Keep receipt metadata privacy-minimized and exclude credentials, cookies, tokens and unnecessary tool parameters.
- Distinguish tool-runtime failure from site rendering, browser-control and assistant-response failures.
Acceptance criteria
- Every ordinary read-only tool call returns a result, a structured failure or a structured timeout within its declared execution bound.
- Pressing stop produces a durable cancellation-request record immediately.
- The operation becomes cancelled only after underlying termination is acknowledged.
- If termination cannot be confirmed within a documented interval, the durable state becomes indeterminate and the UI explains what remains unknown.
- A replacement conversation can retrieve the operation ID and latest state without relying on summarized memory.
- A retry or capability fallback is blocked or warned while the previous operation remains indeterminate.
- Successful underlying completion cannot leave the enclosing orchestration wait pending indefinitely.
- Missing completion events cannot silently wedge later calls in the same session.
- Automated tests cover:
- cancellation before dispatch;
- cancellation during browser, connector, skill and MCP execution;
- underlying completion with a lost outer completion signal;
- timeout without cancellation acknowledgement;
- controller reset and response-stream loss;
- a second read after the first operation becomes indeterminate;
- reconnect and replacement-conversation recovery.
- Receipts reveal no credentials, session material or unnecessary private content.
Related reports
- #26956 — Codex never tells MCP servers to stop after tool call interrupt/timeout covers cancellation propagation from Codex CLI to MCP servers. This report concerns ChatGPT Work and the absence of a user-visible terminal or indeterminate receipt across two different capabilities.
- #32470 — Codex Desktop: Streamable HTTP MCP session wedges after a tool call loses its completion event reports missing completion events followed by indefinitely pending read-only tools. This report has no server-side diagnostic evidence and does not assume the same mechanism.
- #38571 — list threads reaches app server but never completes reports an indefinitely pending read-only Desktop/Remote call without a structured error. This report concerns ChatGPT Work and consecutive browser and continuity-skill operations.
- #40777 — functions.exec cell never settles after nested tool completes demonstrates a completed nested tool whose enclosing wait remains pending. This report cannot establish whether either underlying operation completed.
- #24951 — wait_agent/spawn_agent can block for hours despite timeout_ms records an end-to-end timeout-contract failure in multi-agent operations. This report adds ChatGPT Work evidence without assuming a multi-agent cause.
These reports indicate an adjacent family of timeout, cancellation and lost-completion problems. The present report remains distinct in product surface, observed capabilities and available evidence.
Interim workaround
A private operating runbook now requires:
- choose the lightest direct read;
- state a deadline before execution;
- make one bounded attempt;
- stop the recovery pass on the first stall;
- do not retry, switch capabilities or fall back to Cloud Browser in the same pass;
- classify an unacknowledged manual stop as indeterminate;
- start a later recovery pass only after a new explicit instruction;
- route any possible mutation ambiguity through durable action-receipt reconciliation.
This is a best-effort safeguard. It can bound how long the conversation waits, but it cannot prove that an underlying operation was cancelled.
Privacy
No credentials, cookies, authentication codes, private GitHub content, account identifiers, raw logs, conversation transcript or screenshots are included.
Attachments
None.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
No repository files, tests, or implementation entry points are named. Start by locating the operation lifecycle, cancellation propagation, durable receipt, and retry/fallback handling, then map the listed scenarios into automated tests. Done means bounded terminal outcomes, acknowledged cancellation or indeterminate state, durable recovery across reconnects, and safe retry behavior.
Written by the indexing model from the issue text.
Assessment
- Domain
- backend-api-design, observability
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100