openai / openai/codex

[ChatGPT Work] Read-only tool calls can remain pending after manual stop without a terminal cancellation receipt

Open
#41,681 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug tool-calls
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:

  1. A GitHub inspection through the browser remained pending until manually stopped at 07:44 Europe/Zurich.
  2. 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
  1. Request a read-only inspection of GitHub state through the browser.
  2. Observe that the operation remains pending instead of returning a result, structured error or timeout.
  3. Manually stop the pending operation at 07:44 Europe/Zurich.
  4. Start the next read-only operation, a continuity-skill read.
  5. Observe that the second capability also remains pending.
  6. Wait approximately 42 minutes without a terminal result.
  7. Manually stop the second operation at 08:28 Europe/Zurich.
  8. 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:

  1. apply a documented execution deadline;
  2. expose a stable operation identifier;
  3. return one authoritative state: completed, failed, timed out, cancelled or indeterminate;
  4. propagate cancellation through every active orchestration and tool layer;
  5. acknowledge cancellation only when the underlying operation has actually terminated;
  6. retain a durable terminal or indeterminate receipt across reconnects and replacement conversations;
  7. 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

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:

  1. choose the lightest direct read;
  2. state a deadline before execution;
  3. make one bounded attempt;
  4. stop the recovery pass on the first stall;
  5. do not retry, switch capabilities or fall back to Cloud Browser in the same pass;
  6. classify an unacknowledged manual stop as indeterminate;
  7. start a later recovery pass only after a new explicit instruction;
  8. 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

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

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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.