openclaw - 💡(How to fix) Fix Codex app-server interrupted turns can suppress no-visible-answer handling [1 pull requests]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

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.

Error Message

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

Root Cause

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.

Fix Action

Fixed

Code Example

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"

---

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

---

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.

---

if (turn.status === "interrupted") {
  this.aborted = true;
}

return {
  aborted: this.aborted || turnInterrupted,
  ...
};

---

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 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 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"'

---

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
RAW_BUFFERClick to expand / collapse

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

  1. Use the Codex app-server runtime through OpenClaw.
  2. Let a user-facing turn complete a shell/tool item but produce no final assistant text.
  3. Receive a Codex app-server turn/completed event whose turn status is interrupted.
  4. 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.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

FAQ

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.

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

openclaw - 💡(How to fix) Fix Codex app-server interrupted turns can suppress no-visible-answer handling [1 pull requests]