openclaw - 💡(How to fix) Fix Gateway crashes from unhandled promise: 'Agent listener invoked outside active run' [1 participants]

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…
GitHub stats
openclaw/openclaw#62253Fetched 2026-04-08 03:07:11
View on GitHub
Comments
0
Participants
1
Timeline
0
Reactions
0
Author
Participants

The gateway process crashes with an unhandled promise rejection when an orphaned exec subprocess writes to stdout/stderr after the agent run has ended. This causes the gateway to exit with status 1, and systemd restarts it — which can create a crash loop if the orphan process writes repeatedly.

Error Message

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

Also observed with handleStderr path.

Root Cause

The gateway process crashes with an unhandled promise rejection when an orphaned exec subprocess writes to stdout/stderr after the agent run has ended. This causes the gateway to exit with status 1, and systemd restarts it — which can create a crash loop if the orphan process writes repeatedly.

Fix Action

Workaround

A startup hook that finds orphaned processes with open FDs to .jsonl session files and kills them before the new gateway instance starts processing.

Code Example

[openclaw] Unhandled promise rejection: Error: Agent listener invoked outside active run
    at Agent.processEvents (node_modules/@mariozechner/pi-agent-core/src/agent.ts:533:10)
    at node_modules/@mariozechner/pi-agent-core/src/agent.ts:380:21
    at Object.onUpdate (node_modules/@mariozechner/pi-agent-core/src/agent-loop.ts:539:7)
    at emitUpdate (dist/exec-defaults-uj0McX2k.js:1524:8)
    at handleStdout (dist/exec-defaults-uj0McX2k.js:1546:4)
    at Object.onSupervisorStdout [as onStdout] (dist/exec-defaults-uj0McX2k.js:1610:3)
    ...
    at Socket.<anonymous> (dist/exec-defaults-uj0McX2k.js:568:4)
RAW_BUFFERClick to expand / collapse

Bug Report

Version: 2026.4.5 (3e72c03) Node: v25.6.1 OS: Linux 6.17.13-2-pve (x64), LXC container

Description

The gateway process crashes with an unhandled promise rejection when an orphaned exec subprocess writes to stdout/stderr after the agent run has ended. This causes the gateway to exit with status 1, and systemd restarts it — which can create a crash loop if the orphan process writes repeatedly.

Reproduction

  1. Start the gateway with any agent that has exec-based tools
  2. A cron job or session spawns an exec child process
  3. The gateway restarts (SIGUSR1 for config change, or crashes for another reason)
  4. The exec child process survives the restart (gets reparented to PID 1)
  5. When the orphan process writes to its stdout/stderr pipe, the agent event handler fires Agent.processEvents outside of an active run
  6. Unhandled promise rejection → Node.js exits with code 1

Stack Trace

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

Also observed with handleStderr path.

Observed Impact

  • 10 crashes in ~10 minutes when crash loop occurs
  • Gateway becomes unresponsive during rapid restart cycles
  • All channels (Telegram, Discord) lose connectivity

Expected Behavior

Either:

  1. Kill child processes on SIGUSR1/restart — the gateway should terminate all exec subprocess children before restarting in-process
  2. Handle gracefully — catch the "outside active run" error and ignore it instead of letting it become an unhandled rejection
  3. Both — kill children AND handle the edge case defensively

Workaround

A startup hook that finds orphaned processes with open FDs to .jsonl session files and kills them before the new gateway instance starts processing.

Environment

  • Running in LXC container on Proxmox
  • Multiple agents (ada, k2, cora, winston, synergy) + 4 tool agents
  • 13 cron jobs, several of which use exec tools
  • KillMode=control-group in systemd service (doesn't help for SIGUSR1 in-process restarts)

extent analysis

TL;DR

Implement a mechanism to either kill child processes on restart or handle the "outside active run" error defensively to prevent unhandled promise rejections.

Guidance

  • Identify and terminate orphaned exec subprocesses before restarting the gateway process to prevent them from writing to stdout/stderr after the agent run has ended.
  • Consider implementing a try-catch block around the Agent.processEvents call to catch and ignore the "outside active run" error, preventing it from becoming an unhandled rejection.
  • Review the startup hook workaround that kills orphaned processes with open FDs to .jsonl session files before the new gateway instance starts processing.
  • Verify that the KillMode=control-group setting in the systemd service is correctly configured and effective for the specific restart scenarios.

Example

try {
  Agent.processEvents();
} catch (error) {
  if (error.message === 'Agent listener invoked outside active run') {
    // Ignore the error and continue
  } else {
    throw error;
  }
}

Notes

The provided stack trace and reproduction steps suggest that the issue is related to the handling of orphaned exec subprocesses and the "outside active run" error. However, without further information about the specific requirements and constraints of the system, it is difficult to provide a more detailed solution.

Recommendation

Apply a workaround that kills orphaned processes with open FDs to .jsonl session files before the new gateway instance starts processing, as this approach can help prevent the crash loop and unhandled promise rejections.

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