Replies: 1 comment
|
I can't reproduce this in your environment, but the report is precise enough to name the mechanism. I traced the settlement chain on Why your evidence already rules most of this outYour strongest observation is the pair: settled and hung runs have identical final log rows (the In this provider there are two different terminal authorities, and they are not the same thing:
Plain "pipe closed" is covered: The unbounded await
const waitForExit = async (signal?: AbortSignal): Promise<boolean> => {
if (rangeExitObserved) return true
return waitWithAbort(observeRangeExit(), signal)
}and the no-signal branch in So the picture is: Why foreground codex calls are the ones exposed
The two providers differ in what teardown must conclude first:
Both end at the identical unbounded wait — yet yours is the first report where teardown hangs, and your own control sentence (" Practical conclusions
Disclosure: I could not reproduce the hang, and I have not run this against a live hung instance — the above is a source trace on |
Uh oh!
There was an error while loading. Please reload this page.
Summary
Intermittently, a
subagent_codextool call never returns. The delegated Codex child runs its turn to completion — streamed output, file side effects written — and exits, but the dsh-side run staysRunningforever (UI: "Deep diving…"). Cancellation does nothing. Only restarting the dsh server clears it, and the call is then recorded asThe tool call was interrupted after it was recorded, but no result was durably recorded. Its outcome is unknown./TOOL_OUTCOME_UNKNOWN.This breaks any unattended flow that needs a Codex delegation's return value.
Environment
npm exec @deepseek-ai/dsh web), profileweb@deepseek-ai/dsh-subagent-codexand@deepseek-ai/dsh-subagent-claude-code(toolssubagent_codex/subagent_claude_code;backgroundMode: one-shot,maxDepth: provider-managed)@openai/codex0.153.4 (profile-local); nativecodex-linux-x64app-serverpermissionModevaried during observations (neverdefault,approve-for-me, and a session-level full-access preset); the hang reproduces across all of them, with default read-only sandbox tooFrequency
Over one evening: ≥6 hung calls, ≥9 settled calls. Hangs often cluster within a server instance (a freshly restarted instance hung on its very first Codex call with zero concurrency; another instance ran 5 Codex/Claude calls back-to-back with 5/5 settling). The same short prompt (
git status --short) sometimes settles in ~10 s and sometimes hangs forever.Not concurrency-related in the hung cases: several hangs were the only running call in the whole instance.
Reproduction (nondeterministic — roughly half the time)
dsh webwith a profile exposingsubagent_codex.Use subagent_codex to rungit status --shortand return only its output.Evidence that the hang is dsh-side (the child completes and exits)
Codex children log to
~/.codex/logs_2.sqlite(tablelogs; body columnfeedback_log_body;process_uuid=pid:<n>:…). Children spawned by dsh are identifiable byapp_server.client_name="deepseek-harness"(the VS Code extension logs as"VS Code").Query used:
codex_app_server::outgoing_message: app-server event: item/agentMessage/delta targeted_connections=1.item/agentMessage/delta. The process was gone by 22:44:47 (no child inps); the dsh call was stillRunningminutes later..review-loop/plan.md), streamed its answer, and exited — and the dsh-side call still never settled.So the child's lifecycle and log signature are indistinguishable between settled and hung runs: the child finishes, streams its final answer, and exits; the dsh side simply never concludes the run.
Workarounds attempted
never, read-only),approve-for-me(workspace-write), and a session-level full-access preset — all reproduce; not permission-related.Impact
TOOL_OUTCOME_UNKNOWN, with its result permanently lost — even when the child already performed its file edits.Additional notes
rc.2does not fix this: the subagent packages are byte-identical between rc.1 and rc.2 (onlypackage.jsonversion bumps; rc.2 release notes list two UI changes). Not retested there in depth.ERROR codex_core::tools::router: error=collab spawn failed: no thread with id: …(collab sub-thread vsephemeral: truethread). The child continued fine; likely unrelated, noting it for completeness.subagent_claude_codecalls settled in every observed run (same service, different provider) — but we did not stress it; the file-registration/teardown path difference may matter.Possible investigation pointers (speculative)
@deepseek-ai/dsh-subagent-codex(CodexAppServerWire,settleRunResult,subprocessRunHandle): what does the provider await before publishing a result — a terminalturn/completednotification, child quiescence, or the subprocess owner's "prove it is quiescent" step? The wrapper (node …/@openai/codex/bin/codex.js app-server --stdio→ nativecodex app-server --stdio) exits promptly after streaming; a race between the terminal notification and process exit would match the evidence.ephemeral: truethreads over an app-server--stdioconnection; hung runs show no lingering child, so nothing is left to clean up — the handle in dsh appears orphaned rather than the process.Happy to provide the full sqlite log extracts (or additional fresh reproductions) if useful.
All reactions