Bug type
Behavior bug (incorrect output/state without crash)
Beta release blocker
No
Summary
Codex app-server turn.status: "interrupted" is projected as an OpenClaw abort even when OpenClaw did not explicitly cancel the run, so user-facing turns with only tool output can skip the existing no-visible-answer guard.
Steps to reproduce
- Use the Codex app-server runtime through OpenClaw.
- Let a user-facing turn complete a shell/tool item but produce no final assistant text.
- Receive a Codex app-server
turn/completed event whose turn status is interrupted.
- Observe that OpenClaw marks the attempt as aborted instead of treating it as an incomplete user-visible turn.
Minimal regression evidence from current main before the fix:
CI=1 timeout 180s node scripts/run-vitest.mjs run \
--config test/vitest/vitest.extensions.config.ts \
extensions/codex/src/app-server/event-projector.test.ts \
-t "does not treat app-server interrupted status"
Result before the fix:
FAIL extensions/codex/src/app-server/event-projector.test.ts > CodexAppServerEventProjector > does not treat app-server interrupted status as a user cancellation by itself
AssertionError: expected true to be false
Expected behavior
OpenClaw should keep these states distinguishable:
- explicit OpenClaw/user cancellation,
- OpenClaw timeout,
- Codex app-server interrupted terminal status,
- failed turn,
- completed turn with no visible assistant answer,
- completed tool-only output.
A Codex app-server interrupted completion should not by itself mark the OpenClaw attempt as aborted. If the user is waiting for a response and no visible assistant text exists, OpenClaw should keep the existing incomplete-turn/no-visible-answer handling active instead of silently treating the turn as cancelled.
Actual behavior
extensions/codex/src/app-server/event-projector.ts set this.aborted = true when turn.status === "interrupted" and also returned aborted: this.aborted || turnInterrupted.
That caused the embedded runner to receive aborted: true, and the incomplete-turn guard skipped the user-visible "no answer" path because aborts are intentionally treated differently from incomplete model output.
Observed user-facing symptom from a local OpenClaw dashboard session:
The previous attempt did not produce a user-visible answer. Continue from the current state and produce the visible answer now. Do not restart from scratch.
Immediately before the symptom, the visible transcript contained only a shell/process-inspection tool output and no final assistant answer. Private hostnames, usernames, paths, and IPs are redacted from this report.
OpenClaw version
Reproduced by regression test on official origin/main commit 67c12e036802224e76547092938e3b9759846956.
Observed locally on OpenClaw beta 2026.5.19-beta.1 (ba9034b), but the code path was also present on current official main.
Operating system
Linux x64. Exact local distro details are not required for the regression; the failing behavior is covered by unit tests.
Install method
pnpm/dev checkout for regression tests. Local dashboard observation used an OpenClaw beta wrapper.
Model
Codex app-server runtime with OpenAI Codex model family.
Provider / routing chain
OpenClaw -> Codex app-server runtime.
Additional provider/model setup details
NOT_ENOUGH_INFO
Logs, screenshots, and evidence
Root-cause lines on current main before the fix:
if (turn.status === "interrupted") {
this.aborted = true;
}
return {
aborted: this.aborted || turnInterrupted,
...
};
Focused tests after the fix:
CI=1 timeout 240s node scripts/run-vitest.mjs run \
--config test/vitest/vitest.extensions.config.ts \
extensions/codex/src/app-server/event-projector.test.ts
Test Files 1 passed (1)
Tests 60 passed (60)
CI=1 timeout 240s node scripts/run-vitest.mjs run \
--config test/vitest/vitest.agents-pi-embedded.config.ts \
src/agents/pi-embedded-runner/run.incomplete-turn.test.ts
Test Files 1 passed (1)
Tests 96 passed (96)
Crabbox live environment proof, redacted:
crabbox run --provider ssh --target linux --static-host <redacted-lab-host> \
--static-user <redacted-user> --static-port 22 \
--static-work-root <redacted-workroot> --no-sync -- echo CRABBOX_REMOTE_OK
CRABBOX_REMOTE_OK
run summary sync=0s command=156ms total=180ms sync_skipped=true exit=0
lease cleanup stopped=true policy=auto
Crabbox live regression proof after installing a user-local Node/pnpm toolchain on the lab VM:
crabbox run --provider ssh --target linux --static-host <redacted-lab-host> \
--static-user <redacted-user> --static-port 22 \
--static-work-root <redacted-workroot> --shell -- \
'export PATH="$HOME/.local/bin:$PATH"; node --version; pnpm --version;
pnpm install --frozen-lockfile --ignore-scripts;
CI=1 node scripts/run-vitest.mjs run --config test/vitest/vitest.extensions.config.ts \
extensions/codex/src/app-server/event-projector.test.ts \
-t "app-server interrupted status|sparse successful bash output";
CI=1 node scripts/run-vitest.mjs run --config test/vitest/vitest.agents-pi-embedded.config.ts \
src/agents/pi-embedded-runner/run.incomplete-turn.test.ts \
-t "sparse bash output"'
Result:
event-projector.test.ts: Test Files 1 passed; Tests 2 passed | 58 skipped
run.incomplete-turn.test.ts: Test Files 1 passed; Tests 1 passed | 95 skipped
run summary sync=2.536s command=32.891s total=35.452s exit=0
lease cleanup stopped=true policy=auto
Impact and severity
Affected: OpenClaw users running Codex app-server-backed agent turns.
Severity: High for the affected path. The user can see a tool-only transcript and not receive the requested final answer, making OpenClaw feel like it dropped or cancelled the agent response.
Frequency: NOT_ENOUGH_INFO. The regression is deterministic in the new unit test; live frequency depends on how often Codex app-server emits an interrupted terminal turn without an explicit OpenClaw cancellation.
Consequence: poor UX and interrupted workflows because a user-facing turn can end without a visible assistant answer.
Additional information
This report does not claim that every STOPPED or interrupted state is successful. The requested fix keeps explicit OpenClaw cancellation and timeouts separate while preventing app-server interrupted from suppressing the incomplete-turn guard by itself.
Bug type
Behavior bug (incorrect output/state without crash)
Beta release blocker
No
Summary
Codex app-server
turn.status: "interrupted"is projected as an OpenClaw abort even when OpenClaw did not explicitly cancel the run, so user-facing turns with only tool output can skip the existing no-visible-answer guard.Steps to reproduce
turn/completedevent whose turn status isinterrupted.Minimal regression evidence from current
mainbefore the fix:CI=1 timeout 180s node scripts/run-vitest.mjs run \ --config test/vitest/vitest.extensions.config.ts \ extensions/codex/src/app-server/event-projector.test.ts \ -t "does not treat app-server interrupted status"Result before the fix:
Expected behavior
OpenClaw should keep these states distinguishable:
A Codex app-server
interruptedcompletion should not by itself mark the OpenClaw attempt as aborted. If the user is waiting for a response and no visible assistant text exists, OpenClaw should keep the existing incomplete-turn/no-visible-answer handling active instead of silently treating the turn as cancelled.Actual behavior
extensions/codex/src/app-server/event-projector.tssetthis.aborted = truewhenturn.status === "interrupted"and also returnedaborted: this.aborted || turnInterrupted.That caused the embedded runner to receive
aborted: true, and the incomplete-turn guard skipped the user-visible "no answer" path because aborts are intentionally treated differently from incomplete model output.Observed user-facing symptom from a local OpenClaw dashboard session:
Immediately before the symptom, the visible transcript contained only a shell/process-inspection tool output and no final assistant answer. Private hostnames, usernames, paths, and IPs are redacted from this report.
OpenClaw version
Reproduced by regression test on official
origin/maincommit67c12e036802224e76547092938e3b9759846956.Observed locally on OpenClaw beta
2026.5.19-beta.1 (ba9034b), but the code path was also present on current officialmain.Operating system
Linux x64. Exact local distro details are not required for the regression; the failing behavior is covered by unit tests.
Install method
pnpm/dev checkout for regression tests. Local dashboard observation used an OpenClaw beta wrapper.
Model
Codex app-server runtime with OpenAI Codex model family.
Provider / routing chain
OpenClaw -> Codex app-server runtime.
Additional provider/model setup details
NOT_ENOUGH_INFO
Logs, screenshots, and evidence
Root-cause lines on current
mainbefore the fix:Focused tests after the fix:
Crabbox live environment proof, redacted:
Crabbox live regression proof after installing a user-local Node/pnpm toolchain on the lab VM:
Result:
Impact and severity
Affected: OpenClaw users running Codex app-server-backed agent turns.
Severity: High for the affected path. The user can see a tool-only transcript and not receive the requested final answer, making OpenClaw feel like it dropped or cancelled the agent response.
Frequency: NOT_ENOUGH_INFO. The regression is deterministic in the new unit test; live frequency depends on how often Codex app-server emits an
interruptedterminal turn without an explicit OpenClaw cancellation.Consequence: poor UX and interrupted workflows because a user-facing turn can end without a visible assistant answer.
Additional information
This report does not claim that every
STOPPEDorinterruptedstate is successful. The requested fix keeps explicit OpenClaw cancellation and timeouts separate while preventing app-serverinterruptedfrom suppressing the incomplete-turn guard by itself.