Conversation
When the Codex CLI spawn timeout fires, the transport reported "Codex CLI exited with code -1" followed by the process's stderr. Neither half named the cause. -1 is a sentinel this file invents and Codex never returns, so the message described a crash that did not happen. The line that did name the cause was appended to the tail of stderr, which by then may hold a full STDERR_LIMIT_BYTES of unrelated output, so what the user reads is whatever Codex printed at startup rather than the timeout. The timeout now travels in its own field. done_payload() emits timedOut and timeoutMinutes alongside code, and code carries whatever the child reported instead of being overwritten. code is None on that path because the timeout task removes the child handle in order to kill it, not because a status was observed, so timedOut is the only dependable signal that a run was stopped. The frontend checks it ahead of both existing branches: the exit-code branch skips null outright, and the branch after it calls onDone once any agent message has arrived, so a timeout that had already produced partial output would otherwise have been reported as a success. The message states only what was observed -- that LLM Wiki did not see the run report completion and stopped waiting. It does not say the CLI crashed or that the kill succeeded, because the child can exit on its own just before the deadline and still be marked timed out. The captured diagnostic is kept below the cause, under a heading naming the stream it came from. Two smaller corrections in the same block: the [stderr truncated] marker was suppressed on timeouts by an else-if and now applies to them too, and the done payload's key names are pinned by a Rust test rather than by reading the two files side by side. That test covers the Rust half only; the frontend can still drift independently. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #718.
When the Codex CLI spawn timeout fires, users saw
Codex CLI exited with code -1:followed by the process's stderr.-1is a sentinelcodex_cli.rsinvents, not something Codex returns, so the message named a crash that never
happened. The sentence that did name the cause was appended to the tail of
stderr, behind up to
STDERR_LIMIT_BYTESof unrelated startup output, so it waseffectively invisible.
Changes
src-tauri/src/commands/codex_cli.rsdone_payload()emitstimedOutandtimeoutMinutesas their own fields.codenow carries whatever the child reported instead of being overwrittenwith
-1.structured now. A consequence worth naming:
[stderr truncated]wassuppressed on timeouts by the
else ifthat carried that append, and nowapplies to them too.
src/lib/codex-cli-transport.tstimedOutis checked ahead of both existing branches. This ordering isload-bearing rather than cosmetic: the timeout task removes the child handle
in order to kill it, so
codeisnullhere on every platform. Theexit-code branch skips
nulloutright, and the branch after it callsonDoneonce any agent message has arrived, so a timeout that had alreadyproduced partial output would be reported to the user as a success.
under a heading naming the stream it actually came from. It states only what
was observed, that LLM Wiki did not see the run report completion and stopped
waiting, rather than that the CLI crashed or that the kill succeeded: the
child can exit on its own just before the deadline and still be marked timed
out.
Scope and limits
codeisNoneon the timeout path because the handle was taken away, notbecause a status was observed.
start_kill()'s result is still unchecked;this change does not try to fix that, it stops the message from claiming
otherwise.
hand and can still drift independently; nothing here exercises a real Tauri
emit end to end.
from before this patch, where the same race produced code
-1.codex --versiontimeoutand applies cleanly over this change; the two do not overlap.
Tests
src/lib/codex-cli-transport.test.ts, 17 passing. Three added:calling
onDone. This is the regression the ordering exists to prevent; itfails if the
timedOutcheck moves back below the others.stdoutwhen stderr is empty.src-tauri/src/commands/codex_cli.rs, 9 passing, 2 added overdone_payload().Mutating
timedOuttotimed_outturns both red; before this test that typowould have shipped with the whole suite green.
Both the ordering assertion and the key-name assertion were mutation-tested by
reverting the behaviour they guard and confirming a named test goes red.
Verification
npm run build,npm run test:mocks(132 files / 1879 tests),npm run mcp:test(22/22),cargo build,cargo test,cargo fmt --check,git diff --check.