openclaw - ✅(Solved) Fix Unhandled promise rejection: Agent listener invoked outside active run when subprocess stdout arrives after agent run ends [1 pull requests, 3 comments, 4 participants]

Official PRs (…)
ON THIS PAGE

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…
GitHub stats
openclaw/openclaw#62477Fetched 2026-04-08 03:03:44
View on GitHub
Comments
3
Participants
4
Timeline
5
Reactions
0
Author
Timeline (top)
commented ×3cross-referenced ×2

Error Message

[openclaw] Unhandled promise rejection: Error: Agent listener invoked outside active run
 at Agent.processEvents (file:///C:/Users/buw/AppData/Roaming/npm/node_modules/openclaw/node_modules/@mariozechner/pi-agent-core/src/agent.ts:533:10)
 at file:///C:/Users/buw/AppData/Roaming/npm/node_modules/openclaw/node_modules/@mariozechner/pi-agent-core/src/agent.ts:380:21
 at Object.onUpdate (file:///C:/Users/buw/AppData/Roaming/npm/node_modules/openclaw/node_modules/@mariozechner/pi-agent-core/src/agent-loop.ts:539:7)
 at emitUpdate (file:///C:/Users/buw/AppData/Roaming/npm/node_modules/openclaw/dist/exec-defaults-uj0McX2k.js:1524:8)
 at handleStdout (file:///C:/Users/buw/AppData/Roaming/npm/node_modules/openclaw/dist/exec-defaults-uj0McX2k.js:1546:4)
 at Object.onSupervisorStdout [as onStdout] (file:///C:/Users/buw/AppData/Roaming/npm/node_modules/openclaw/dist/exec-defaults-uj0McX2k.js:1610:3)

Fix Action

Fix / Workaround

  • Severity: High — causes complete Gateway crash requiring manual restart
  • Frequency: Every time subprocess stdout arrives after run end
  • Workaround: None available to end users

PR fix notes

PR #62815: fix(exec): prevent gateway crash from agent listener error

Description (problem / solution / changelog)

Summary

Fixes critical gateway crash when subprocess stdout arrives after agent run ends, causing unhandled promise rejection "Agent listener invoked outside active run".

Changes:

  • Add try-catch wrapper around opts.onUpdate() in emitUpdate()
  • Add suppression flag to prevent repeated errors after first failure
  • Proactively disable updates when exec process completes
  • Add comprehensive test coverage (5 new tests, all passing)
  • Add detailed inline documentation explaining the race condition

Fixes

  • #62746 - Gateway crash: Unhandled promise rejection
  • #62520 - Background exec output after subagent run completes
  • #62477 - Subprocess stdout arrives after agent run ends
  • #61741 - Race condition in subagent/session cleanup
  • #62435 - Gateway crash: Agent listener invoked outside active run

Root Cause

Race condition between subprocess lifecycle (exec-runtime) and agent run lifecycle (pi-agent-core). When an agent run completes and clears activeRun, any subprocess still producing stdout triggers opts.onUpdate() which calls Agent.processEvents(). Since activeRun is undefined, it throws an error that becomes an unhandled promise rejection, crashing the gateway.

Solution

Defensive guard with smart suppression:

  1. Try-catch wrapper prevents crash
  2. Suppression flag stops repeated errors
  3. Proactive disabling in promise handlers
  4. Smart logging (warn first, debug subsequent)

Test Plan

  • ✅ All 5 new tests pass (race condition, suppression, PTY, normal operation, backgrounded)
  • ✅ All 164 existing bash-tools tests pass
  • ✅ Verified exec process continues normally after error suppression
  • ✅ Verified logging provides clear context

Impact

  • Prevents gateway crashes occurring every 20-30 minutes under multi-lane operation
  • Affects all platforms (Windows, macOS, Linux)
  • Affects all channels (Telegram, Discord, Slack, WhatsApp, CLI)
  • Resolves 20+ duplicate issues

Changed files

  • CHANGELOG.md (modified, +1/-0)
  • src/agents/bash-tools.exec-runtime.ts (modified, +58/-11)
  • src/agents/bash-tools.exec.on-update-lifecycle.test.ts (added, +106/-0)
  • src/agents/bash-tools.exec.pty-cleanup.test.ts (modified, +6/-6)

Code Example

[openclaw] Unhandled promise rejection: Error: Agent listener invoked outside active run
 at Agent.processEvents (file:///C:/Users/buw/AppData/Roaming/npm/node_modules/openclaw/node_modules/@mariozechner/pi-agent-core/src/agent.ts:533:10)
 at file:///C:/Users/buw/AppData/Roaming/npm/node_modules/openclaw/node_modules/@mariozechner/pi-agent-core/src/agent.ts:380:21
 at Object.onUpdate (file:///C:/Users/buw/AppData/Roaming/npm/node_modules/openclaw/node_modules/@mariozechner/pi-agent-core/src/agent-loop.ts:539:7)
 at emitUpdate (file:///C:/Users/buw/AppData/Roaming/npm/node_modules/openclaw/dist/exec-defaults-uj0McX2k.js:1524:8)
 at handleStdout (file:///C:/Users/buw/AppData/Roaming/npm/node_modules/openclaw/dist/exec-defaults-uj0McX2k.js:1546:4)
 at Object.onSupervisorStdout [as onStdout] (file:///C:/Users/buw/AppData/Roaming/npm/node_modules/openclaw/dist/exec-defaults-uj0McX2k.js:1610:3)

---

subprocess stdout event
handleStdout (exec-defaults-uj0McX2k.js:1546)
emitUpdate (line 1524, opts.onUpdate callback)
Agent.processEvents (pi-agent-core agent.ts:380)
Error: "Agent listener invoked outside active run"
Unhandled promise rejection
Gateway process crashes
RAW_BUFFERClick to expand / collapse

Bug Description

OpenClaw 版本:2026.4.5 操作系统:Windows (Native, no WSL2) 模型:minimax-portal/MiniMax-M2.7

当一个 agent run 结束后,如果 subprocess 仍在写入 stdout,传入的 stdout 数据会触发 Agent.processEvents,但此时 run 已经不存在(!run),导致未捕获的 Promise 拒绝,进而导致 Gateway 进程崩溃。

Error Message

[openclaw] Unhandled promise rejection: Error: Agent listener invoked outside active run
 at Agent.processEvents (file:///C:/Users/buw/AppData/Roaming/npm/node_modules/openclaw/node_modules/@mariozechner/pi-agent-core/src/agent.ts:533:10)
 at file:///C:/Users/buw/AppData/Roaming/npm/node_modules/openclaw/node_modules/@mariozechner/pi-agent-core/src/agent.ts:380:21
 at Object.onUpdate (file:///C:/Users/buw/AppData/Roaming/npm/node_modules/openclaw/node_modules/@mariozechner/pi-agent-core/src/agent-loop.ts:539:7)
 at emitUpdate (file:///C:/Users/buw/AppData/Roaming/npm/node_modules/openclaw/dist/exec-defaults-uj0McX2k.js:1524:8)
 at handleStdout (file:///C:/Users/buw/AppData/Roaming/npm/node_modules/openclaw/dist/exec-defaults-uj0McX2k.js:1546:4)
 at Object.onSupervisorStdout [as onStdout] (file:///C:/Users/buw/AppData/Roaming/npm/node_modules/openclaw/dist/exec-defaults-uj0McX2k.js:1610:3)

Call Chain

subprocess stdout event
  → handleStdout (exec-defaults-uj0McX2k.js:1546)
    → emitUpdate (line 1524, opts.onUpdate callback)
      → Agent.processEvents (pi-agent-core agent.ts:380)
        → Error: "Agent listener invoked outside active run"
          → Unhandled promise rejection
            → Gateway process crashes

Trigger Scenario

  1. A subagent or exec task completes its run (run context ends)
  2. The subprocess associated with the task is still producing stdout output
  3. The stdout data arrives via the Socket stream
  4. handleStdout calls emitUpdate which invokes the agent's onUpdate callback
  5. Agent.processEvents is called but run is null → throws "Agent listener invoked outside active run"
  6. This unhandled rejection crashes the Gateway process

Additional Context

  • This also happens when MiniMax M2.7 model times out and triggers a failover — the failover logic triggers the same error path
  • The bug is reproducible: it happens consistently when subprocess stdout arrives after the agent run has ended
  • Gateway must be restarted manually after each occurrence

Suggested Fix

In agent.ts around line 380, the onUpdate callback should check if a valid run exists before calling Agent.processEvents. If !run, the callback should be a no-op rather than throwing an error.

Alternatively, in exec-defaults-uj0McX2k.js, the emitUpdate function should guard against calling onUpdate when the associated session's run has already ended.

Impact

  • Severity: High — causes complete Gateway crash requiring manual restart
  • Frequency: Every time subprocess stdout arrives after run end
  • Workaround: None available to end users

extent analysis

TL;DR

The most likely fix is to modify the onUpdate callback in agent.ts to check for a valid run before calling Agent.processEvents, preventing unhandled promise rejections when subprocess stdout arrives after the agent run has ended.

Guidance

  • Check the agent.ts file around line 380 and modify the onUpdate callback to include a check for a valid run before calling Agent.processEvents.
  • Consider adding a guard in exec-defaults-uj0McX2k.js to prevent emitUpdate from calling onUpdate when the associated session's run has already ended.
  • Verify that the fix works by reproducing the error scenario and checking that the Gateway process no longer crashes.
  • Review the failover logic for the MiniMax M2.7 model to ensure it does not trigger the same error path.

Example

// In agent.ts around line 380
onUpdate: (update) => {
  if (run) { // Check if a valid run exists
    Agent.processEvents(update);
  } else {
    // No-op or log a warning
  }
}

Notes

The suggested fix assumes that the onUpdate callback is the correct place to add the check for a valid run. Additional logging or debugging may be necessary to confirm this.

Recommendation

Apply the workaround by modifying the onUpdate callback in agent.ts to check for a valid run before calling Agent.processEvents, as this is a targeted fix that addresses the root cause of the issue.

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…

Still need to ship something?

×6

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

Back to top recommendations

TRENDING