Skip to content

fix(agents): prevent exec tool errors from leaking to channels (#9651)#10261

Closed
nu-gui wants to merge 2 commits intoopenclaw:mainfrom
nu-gui:fix/9651-exec-error-leaks-to-channel
Closed

fix(agents): prevent exec tool errors from leaking to channels (#9651)#10261
nu-gui wants to merge 2 commits intoopenclaw:mainfrom
nu-gui:fix/9651-exec-error-leaks-to-channel

Conversation

@nu-gui
Copy link
Copy Markdown

@nu-gui nu-gui commented Feb 6, 2026

Summary

  • When the exec tool returns a non-zero exit code, stderr/stdout content was forwarded as a visible message to the active messaging channel (WhatsApp, Telegram, etc.), leaking internal details
  • Skip calling emitToolOutput() when isToolError is true in handleToolExecutionEnd(), so error content stays in the agent context only and is never forwarded to channels

Fixes #9651

Test plan

  • 4 new tests for handleToolExecutionEnd(): successful output emission, error output suppression (isError flag), error output suppression (isToolResultError detection), lastToolError recording
  • All 4 tests pass
  • pnpm check passes (0 warnings, 0 errors)

Greptile Overview

Greptile Summary

  • Updates handleToolExecutionEnd to skip emitToolOutput() when the tool execution is considered an error (isError or isToolResultError).
  • Adds a new Vitest suite exercising success emission, suppression on isError, suppression via isToolResultError, and lastToolError recording.
  • Intended to prevent exec/batch stderr/stdout from being forwarded to external messaging channels by avoiding the tool-output emission path.

Confidence Score: 3/5

  • This PR likely addresses one leak path, but may still allow error tool output to be surfaced via tool result events.
  • Change correctly gates emitToolOutput() behind !isToolError and adds tests for that behavior, but emitAgentEvent still includes result: sanitizedResult even on error; if any downstream consumer forwards tool result events to external channels, the original leak may persist. Confidence is reduced until the full external-forwarding path is confirmed/redacted.
  • src/agents/pi-embedded-subscribe.handlers.tools.ts (error tool result emission via emitAgentEvent)

When exec tool returns a non-zero exit code, stderr/stdout content was
forwarded as a visible message to the active messaging channel, leaking
internal details. Skip emitting tool output when the tool result is an
error so sensitive process output stays in the agent context only.
Copy link
Copy Markdown
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 files reviewed, 2 comments

Edit Code Review Agent Settings | Greptile

Comment on lines +1 to +3
import { describe, expect, it, vi } from "vitest";
import type { EmbeddedPiSubscribeContext } from "./pi-embedded-subscribe.handlers.types.js";
import { handleToolExecutionEnd } from "./pi-embedded-subscribe.handlers.tools.js";
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing coverage for leak

The new tests assert that emitToolOutput isn’t called on error, but they don’t cover the actual leak vector described in the PR (“forwarded as a visible message to the active messaging channel”). Since handleToolExecutionEnd still emits emitAgentEvent(... result: sanitizedResult) on errors, a regression test should assert that error results are not emitted (or are redacted) on whichever callback/path is responsible for external channel forwarding, otherwise this could reintroduce the leak via a different emitter.

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/agents/pi-embedded-subscribe.handlers.tools.test.ts
Line: 1:3

Comment:
**Missing coverage for leak**

The new tests assert that `emitToolOutput` isn’t called on error, but they don’t cover the actual leak vector described in the PR (“forwarded as a visible message to the active messaging channel”). Since `handleToolExecutionEnd` still emits `emitAgentEvent(... result: sanitizedResult)` on errors, a regression test should assert that error results are not emitted (or are redacted) on whichever callback/path is responsible for external channel forwarding, otherwise this could reintroduce the leak via a different emitter.

How can I resolve this? If you propose a fix, please make it concise.

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Feb 6, 2026

Additional Comments (1)

src/agents/pi-embedded-subscribe.handlers.tools.ts
Errors still forwarded

This change only suppresses emitToolOutput(...), but handleToolExecutionEnd still always emits the full sanitizedResult on the emitAgentEvent({ stream: "tool", phase: "result", ... result: sanitizedResult }) path even when isToolError is true (see around isToolError = isError || isToolResultError(result)). If any consumer bridges these tool events into external channels (or logs accessible to users), stderr/stdout can still leak. If the goal is “never forwarded to channels,” consider omitting/redacting result for error tool events (or ensuring downstream tool-event consumers never surface result to channels).

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/agents/pi-embedded-subscribe.handlers.tools.ts
Line: 161:163

Comment:
**Errors still forwarded**

This change only suppresses `emitToolOutput(...)`, but `handleToolExecutionEnd` still always emits the full `sanitizedResult` on the `emitAgentEvent({ stream: "tool", phase: "result", ... result: sanitizedResult })` path even when `isToolError` is true (see around `isToolError = isError || isToolResultError(result)`). If any consumer bridges these tool events into external channels (or logs accessible to users), stderr/stdout can still leak. If the goal is “never forwarded to channels,” consider omitting/redacting `result` for error tool events (or ensuring downstream tool-event consumers never surface `result` to channels).

How can I resolve this? If you propose a fix, please make it concise.

Redact the tool result payload from emitAgentEvent when isToolError is
true, preventing stderr/stdout from leaking through event consumers
that may bridge to external channels. Add tests verifying the agent
event path omits results for errors while including them for successes.
@openclaw-barnacle
Copy link
Copy Markdown

This pull request has been automatically marked as stale due to inactivity.
Please add updates or it will be closed.

@openclaw-barnacle openclaw-barnacle bot added the stale Marked as stale due to inactivity label Feb 21, 2026
@openclaw-barnacle openclaw-barnacle bot removed the stale Marked as stale due to inactivity label Feb 24, 2026
@steipete
Copy link
Copy Markdown
Contributor

Closing as AI-assisted stale-fix triage.

Linked issue #9651 ("[Bug]: Exec tool error output (non-zero exit code) sent as message to active WhatsApp/Telegram channel") is currently CLOSED and was closed on 2026-02-23T01:47:22Z with state reason COMPLETED.
Given that issue state, this fix PR is no longer needed in the active queue and is being closed as stale.

If the underlying bug is still reproducible on current main, please reopen this PR (or open a new focused fix PR) and reference both #9651 and #10261 for fast re-triage.

@steipete
Copy link
Copy Markdown
Contributor

Closed after AI-assisted stale-fix triage (closed issue duplicate/stale fix).

@steipete steipete closed this Feb 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Exec tool error output (non-zero exit code) sent as message to active WhatsApp/Telegram channel

2 participants