Skip to content

[macOS Desktop plus Android Remote] list threads reaches app server but never completes; UI sidebar remains healthy. #38571

Open

Description

@charlesvardeman

What version of the Codex App are you using (From “About Codex” dialog)?

26.810.41047

What subscription do you have?

Pro x 20

What platform is your computer?

Darwin 24.6.0 arm64 arm

What issue are you seeing?

The Desktop UI continues to show projects, pinned chats, and recent chats, but agent-facing codex_app thread-management calls are unreliable on both Desktop and Android Remote.

An agent list_threads call can remain pending indefinitely with no structured error, preventing a fresh task from discovering existing conversations that are visible in the UI.

Remote project creation also failed with:

create_thread received invalid arguments

What steps can reproduce the bug?

  1. Pair ChatGPT on Android with a local macOS Codex Desktop host.
  2. Confirm that projects and existing chats remain visible in the Desktop UI.
  3. From an agent task, call codex_app.list_threads.
  4. Observe that the call can remain pending indefinitely without a result or structured error.
  5. Restart Desktop and retry. The UI sidebar can still list chats, while a later agent-facing list call again fails to settle.

Read-only log evidence from the failing session:

  • Immediately after restart, UI-originated thread/list completed in roughly 1–11 ms.
  • Later, four thread/list requests reached the local app-server.
  • No matching completion/response record was logged for those request IDs.
  • After pending calls were cancelled, the app-server logged CancelledError followed by could not find callback.
  • Unrelated account, configuration, filesystem, and thread-read requests continued to complete promptly.

What is the expected behavior?

Every codex_app thread-management call should return either a result or a structured, bounded timeout/error.

Agent-facing thread discovery should not fail while the Desktop UI can list the same chats. Remote project discovery must return identifiers accepted by project task creation for the same caller.

Additional information

The session index JSONL and global JSON parsed successfully, and the thread-state SQLite database passed its integrity check. No local state was modified.

No correlated Remote-disconnect, EPIPE, or thread_list_unavailable event appeared in the inspected log window.

Related issues: #32553, #36404, and #37668. This case is closest to that family but differs from #37668 because the local thread/list requests did reach the app-server before failing to settle.

Prompts, absolute paths, conversation IDs, and raw logs are intentionally omitted for privacy; redacted diagnostics can be provided through a private support channel.

Activity

  1. added
    bugSomething isn't working
    app-serverIssues involving app server protocol or interfaces
    tool-callsIssues related to tool calling
    on Aug 14, 2026
  2. github-actions commented on Aug 14, 2026

    @github-actions
    Contributor
  3. atlys-hein commented on Aug 18, 2026

    @atlys-hein

    Additional current-build reproduction from macOS desktop scheduled automation:

    • Codex app: 26.810.52044 (build 6662)
    • Bundled CLI/app-server: 0.148.0-alpha.9
    • Platform: macOS 26.5.2 arm64
    • Subscription: Pro

    A standalone projectless cron automation called list_threads({ limit: 10 }) exactly once, sequentially, with no other thread-management calls in flight. The call did not return within 30 seconds. The same list_threads({ limit: 10 }) call from a foreground interactive task completed in 1.44 seconds, and later in 1.17 seconds. Restarting Desktop does not prevent the failure from recurring in later tasks.

    Local integrity controls all passed:

    • state DB PRAGMA quick_check: ok
    • rollout/state inventory parity: no missing, stale, duplicate, or malformed rows
    • codex doctor --json: state databases and provider/WebSocket reachability healthy

    An additional correlated finding may explain why the task-service path becomes overloaded: read_thread({ includeOutputs: false, maxOutputCharsPerItem: 1000, turnLimit: 1 }) returned a 3,809,394-byte response for a completed thread because three imageGeneration.result blobs were included without truncation (approximately 1.40 MB, 1.32 MB, and 1.05 MB). The tool ignored both includeOutputs: false and maxOutputCharsPerItem for those items.

    The active rollout inventory also contained three legacy histories of approximately 566 MB, 374 MB, and 178 MB. The built-in migrate-rollouts dry run marked all three eligible for paginated history. Migrating two completed histories and archiving those completed tasks restored foreground list_threads(limit: 10) latency to 1.17 seconds, but this does not explain or fix why the standalone scheduled call can remain pending while the foreground call succeeds.

    This provides two likely interacting defects:

    1. Background/standalone task-management routing can stop settling even while foreground routing remains healthy.
    2. read_thread can return multi-megabyte image payloads despite explicit output suppression/truncation, increasing queue and memory pressure.

    No private paths, prompts, task titles, identifiers, or raw logs are included here. I can provide narrow correlation details privately if needed.

  4. nos1609 commented on Aug 26, 2026

    @nos1609

    Additional sanitized current-build reproduction narrows the hang to the return leg after the App Server has already answered.

    Environment:

    • Windows Codex Desktop package 26.820.7780.0, ARM64
    • bundled task runtime 0.149.0-alpha.4.1
    • directly user-created foreground local task
    • list_threads({ limit: 10 })

    Observed:

    1. The dynamic app-tool log recorded dynamic_app_tool_renderer_execution_started for list_threads.
    2. The corresponding underlying thread/list requests reached AppServerConnection.
    3. The App Server responses were routed successfully in 17 ms and 43 ms with errorCode=null, hadPending=true, and targetDestroyed=false.
    4. The dynamic tool layer never logged its normal Sending server response ... tool=list_threads event.
    5. The originating rollout ends at the list_threads function call with no function-call output and remains unchanged for more than 43 minutes.
    6. A second independent foreground task invoked list_threads during the same incident; it also remained pending until manually interrupted after 495.8 seconds.
    7. Exact-ID read_thread and wait_threads operations remained responsive, and unrelated App Server operations continued completing.

    Earlier list_threads calls in the same Desktop process normally completed in roughly 2-3 seconds. The first unreplied dynamic call appears to poison subsequent agent-facing list calls globally.

    This is one boundary later than the original reproduction: the request not only reaches the App Server, but successful thread/list responses are already routed. The unresolved promise is between the routed App Server response and the dynamic app-tool reply to the model.

    Expected: every dynamic task-tool request must settle with a result or bounded structured error. A successfully routed App Server response must not leave the model turn blocked indefinitely.

    No task IDs, turn IDs, call IDs, paths, project names, prompts, account data, hostnames, addresses, or credentials are included.

  5. nos1609 commented on Aug 26, 2026

    @nos1609

    Cancellation control from the same incident:

    • the first unreplied list_threads belonged to a turn that later persisted a turn_aborted event;
    • that aborted turn never received a tool response;
    • approximately 80 seconds after the abort, a fresh turn in the same task started normally;
    • its later list_threads call also remained unresolved;
    • a third list call from another foreground task then hung for 495.8 seconds.

    Therefore outer turn cancellation does not reliably cancel or reject the pending dynamic app-tool request. The leaked request survives turn_aborted and appears to poison subsequent list_threads calls in the renderer bridge.

    Required invariant: aborting a turn must cancel every outstanding app-tool request, reject the model-visible tool promise, remove the call from bridge bookkeeping, and permit the next task-tool call to proceed. A stale request must not survive into later turns.

    No task, turn, call, project, path, host, or account identifiers are included.

  6. nos1609 commented on Aug 26, 2026

    @nos1609

    Recovery outcome from the same current-build incident:

    • Invoking the visible Stop control immediately appended turn_aborted for the blocked outer turn in the durable rollout.
    • The unresolved list_threads call had not settled naturally. Its model-visible output appeared only during cancellation, roughly 57 minutes after the original call.
    • The App Server process was not restarted.
    • A renderer-only reload was performed, then the task was reopened.
    • A fresh turn started normally. Exact-ID wait_threads, exact-ID read_thread, and dynamic command calls returned, and the new tool stream became visible in the UI.
    • list_threads was intentionally not retried, so this does not claim that the poisoned list route recovered.

    This confirms two separate recovery boundaries: Stop can terminate the outer turn, but the leaked dynamic request remains unresolved until cancellation; restoring normal renderer tool delivery still requires a renderer reload. Cancellation should settle the tool promise immediately and remove its bridge state without requiring a reload.

    No task, turn, call, project, path, host, account, prompt, or credential identifiers are included.

  7. yankay commented on Sep 30, 2026

    @yankay

    Similar hang with artifact tools

    On 2026-09-29, using a phone to access a Linux host running app-server 0.158.0:

    • codex_app.list_artifacts remained pending for 488.5 seconds until canceled.
    • During that wait, another task on the same app-server process completed the same tool in 0.32 seconds.
    • codex_app.attach_artifact subsequently hung for about 510 seconds until canceled.

    This happens intermittently across multiple tasks. Historical timing logs also show later shell commands waiting behind app-tool calls for over an hour, despite executing in milliseconds.

    Expected: return a result or a bounded error instead of blocking indefinitely. For attachment writes, a timeout should indicate whether the operation may already have taken effect.

    The setup uses LiteLLM; no stock-provider comparison has been performed. The root cause is still unknown.

  8. yankay commented on Oct 14, 2026

    @yankay

    An additional detail from my artifact-tool hang: macOS Codex Desktop is connected to the same remote machine twice through different SSH ports, appearing as two separate remotes. With both connections active, artifact-tool calls hang. Possibly related to #35894, though the underlying cause is not yet confirmed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    appIssues related to the Codex desktop appapp-serverIssues involving app server protocol or interfacesbugSomething isn't workingremotetool-callsIssues related to tool calling

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions