openclaw - ✅(Solved) Fix [Bug]: Gateway crashes with unhandled promise rejection when exec'd process writes to stderr after agent run ends [1 pull requests, 3 comments, 3 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#63699Fetched 2026-04-10 03:42:10
View on GitHub
Comments
3
Participants
3
Timeline
9
Reactions
0
Author
Timeline (top)
commented ×3cross-referenced ×2labeled ×1mentioned ×1

When a command launched via the exec tool writes to stderr after the agent run (turn) has already completed, the gateway crashes with an unhandled promise rejection.

The exec module attempts to push the late-arriving stderr output to the agent run context, but the run no longer exists. This throws an exception that is not caught, causing the entire gateway process to terminate.

Root cause:

The exec module does not detach or guard its stdio listeners when the owning agent run completes. Any process that produces stderr output after the run ends — due to stdio buffer flush delays, background processing, or simply slow I/O — will trigger this crash.

Any command invoked via exec that writes to stderr after the agent turn finishes (e.g. ffmpeg, curl with verbose output, any long-running process) will reproduce the same crash.

Expected behavior:

The exec module should gracefully handle stderr/stdout arriving after the agent run ends — either by detaching listeners when the run completes, or by catching and discarding push failures. The gateway should not crash due to late-arriving stdio output from a child process.

Error Message

The exec module attempts to push the late-arriving stderr output to the agent run context, but the run no longer exists. This throws an exception that is not caught, causing the entire gateway process to terminate.

Root Cause

Root cause:

Fix Action

Fixed

PR fix notes

PR #63842: fix(process): destroy stdio streams on dispose to prevent gateway crash

Description (problem / solution / changelog)

Summary

child.removeAllListeners() only removes listeners from the ChildProcess EventEmitter but not from stdio streams. This fix destroys stdio streams on dispose to prevent gateway crashes from dangling stream listeners.

Closes #63699

Testing

  • Relevant tests pass

This PR was developed with AI assistance (Claude). All code has been reviewed and tested. Built with islo.dev

Changed files

  • src/process/supervisor/adapters/child.test.ts (modified, +26/-0)
  • src/process/supervisor/adapters/child.ts (modified, +8/-0)
RAW_BUFFERClick to expand / collapse

Bug type

Crash (process/app exits or hangs)

Beta release blocker

No

Summary

When a command launched via the exec tool writes to stderr after the agent run (turn) has already completed, the gateway crashes with an unhandled promise rejection.

The exec module attempts to push the late-arriving stderr output to the agent run context, but the run no longer exists. This throws an exception that is not caught, causing the entire gateway process to terminate.

Root cause:

The exec module does not detach or guard its stdio listeners when the owning agent run completes. Any process that produces stderr output after the run ends — due to stdio buffer flush delays, background processing, or simply slow I/O — will trigger this crash.

Any command invoked via exec that writes to stderr after the agent turn finishes (e.g. ffmpeg, curl with verbose output, any long-running process) will reproduce the same crash.

Expected behavior:

The exec module should gracefully handle stderr/stdout arriving after the agent run ends — either by detaching listeners when the run completes, or by catching and discarding push failures. The gateway should not crash due to late-arriving stdio output from a child process.

Steps to reproduce

Ask the agent to run a command via exec (host=gateway) that produces delayed stderr output — for example:

ffmpeg -i input.mp4 -c:v libx264 -preset slow output.mp4 FFmpeg writes encoding progress and codec warnings to stderr. Due to stdio buffer flush timing, some of this output may arrive after the process exits.

The agent reads stdout, receives the exec result (exit code 0), generates a response, and the agent run ends.

Shortly after, buffered stderr data from the child process flushes through the pipe.

Gateway crashes with an unhandled promise rejection.

Expected behavior

The exec module should wait for all stdio pipes to close (end event) before resolving — not just the process exit event. If output still arrives after the agent run ends, it should be discarded gracefully rather than crashing the gateway.

Actual behavior

openclaw gateway stops.

OpenClaw version

2026.4.5

Operating system

Windows 11

Install method

No response

Model

anthropic/claude-4.6.opus

Provider / routing chain

slack -> openclaw -> gateway -> claude

Additional provider/model setup details

No response

Logs, screenshots, and evidence

Impact and severity

No response

Additional information

No response

extent analysis

TL;DR

The gateway crash can be fixed by modifying the exec module to detach or guard its stdio listeners when the agent run completes, handling late-arriving stderr output gracefully.

Guidance

  • Review the exec module's implementation to ensure it properly handles stdio listeners after the agent run completes, considering stdio buffer flush delays and background processing.
  • Modify the exec module to catch and discard push failures for stderr/stdout arriving after the agent run ends, preventing unhandled promise rejections.
  • Consider adding a timeout or a mechanism to wait for all stdio pipes to close (end event) before resolving, rather than relying solely on the process exit event.
  • Test the modified exec module with commands that produce delayed stderr output, such as ffmpeg, to verify the fix.

Example

// Pseudo-code example, actual implementation may vary
execModule.on('stdioListenerEnd', () => {
  // Detach or guard stdio listeners when agent run completes
  // ...
});

execModule.on('stderrOutput', (output) => {
  if (agentRunCompleted) {
    // Discard late-arriving stderr output
    return;
  }
  // Handle stderr output
  // ...
});

Notes

The provided information suggests that the issue is specific to the exec module's handling of stdio listeners and late-arriving output. The fix should focus on modifying the exec module to handle these scenarios gracefully.

Recommendation

Apply workaround: Modify the exec module to handle late-arriving stderr output and detach or guard stdio listeners when the agent run completes, as this approach directly addresses the root cause of the gateway crash.

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

The exec module should wait for all stdio pipes to close (end event) before resolving — not just the process exit event. If output still arrives after the agent run ends, it should be discarded gracefully rather than crashing the gateway.

Still need to ship something?

×6

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

Back to top recommendations

TRENDING