openclaw - ✅(Solved) Fix [Bug] exec tool emits empty text content block when command produces no stdout [3 pull requests, 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#73117Fetched 2026-04-28 06:27:23
View on GitHub
Comments
0
Participants
1
Timeline
4
Reactions
0
Participants
Timeline (top)
cross-referenced ×3closed ×1

When an exec command produces no stdout (e.g. grep with no matches, mkdir, cp, silent git commands), the exec runtime constructs a tool_result content block with text: "". Anthropic's API rejects empty text content blocks, causing the session to error out — typically after bulk operations that include several silent commands.

Error Message

When an exec command produces no stdout (e.g. grep with no matches, mkdir, cp, silent git commands), the exec runtime constructs a tool_result content block with text: "". Anthropic's API rejects empty text content blocks, causing the session to error out — typically after bulk operations that include several silent commands. Run several in sequence in a session — subsequent API call fails with content block validation error.

Root Cause

In bash-tools.exec-runtime:

const tailText = session.tail || session.aggregated;
const warningText = opts.warnings.length ? `${opts.warnings.join("\n")}\n\n` : "";
opts.onUpdate({
  content: [{
    type: "text",
    text: warningText + (tailText || "")  // ← empty string when no output
  }],
  ...
});

When both warningText and tailText are empty, text becomes "".

Fix Action

Fix

text: warningText + (tailText || "(no output)")

Single-character change. Falls back to a non-empty placeholder only when the command produced no output, keeping existing behaviour for all non-empty cases.

PR fix notes

PR #73125: fix(exec): emit "(no output)" placeholder for empty content blocks

Description (problem / solution / changelog)

Fixes #73117.

Problem

When an exec command produces no stdout (e.g. grep with no matches, mkdir, cp, silent git commands), the runtime constructs a tool_result content block with text: "". Anthropic's API rejects empty text content blocks, causing the session to error out after sequences of silent commands.

Fix

Two single-character changes that fall back to a non-empty (no output) placeholder only when the command produced no output, mirroring the existing behavior in buildExecForegroundResult (bash-tools.exec.ts:87):

  • src/agents/bash-tools.exec-runtime.tsemitUpdate() partial-result path
  • src/agents/bash-tools.exec-host-node-phases.tsformatNodeRunToolResult() node-host path

No behavior change for any non-empty output case.

Changed files

  • src/agents/bash-tools.exec-host-node-phases.ts (modified, +1/-1)
  • src/agents/bash-tools.exec-runtime.ts (modified, +1/-1)

PR #73126: fix(exec): avoid empty update text blocks

Description (problem / solution / changelog)

Summary

  • Render a (no output) placeholder when an exec update would otherwise emit an empty text block
  • Preserve existing non-empty output and warning text behavior
  • Add regression coverage for empty, non-empty, and warning-only exec update text

Fixes #73117

Validation

  • pnpm exec oxfmt --write --threads=1 src/agents/bash-tools.exec-runtime.ts src/agents/bash-tools.exec-runtime.test.ts
  • node scripts/run-vitest.mjs run --config test/vitest/vitest.agents.config.ts src/agents/bash-tools.exec-runtime.test.ts
  • pnpm exec oxlint src/agents/bash-tools.exec-runtime.ts src/agents/bash-tools.exec-runtime.test.ts
  • pnpm check:test-types

Changed files

  • CHANGELOG.md (modified, +1/-0)
  • src/agents/anthropic-transport-stream.test.ts (modified, +107/-0)
  • src/agents/anthropic-transport-stream.ts (modified, +24/-16)
  • src/agents/bash-tools.exec-host-node-phases.ts (modified, +2/-1)
  • src/agents/bash-tools.exec-host-node.test.ts (modified, +40/-0)
  • src/agents/bash-tools.exec-output.ts (added, +10/-0)
  • src/agents/bash-tools.exec-runtime.test.ts (modified, +24/-0)
  • src/agents/bash-tools.exec-runtime.ts (modified, +6/-2)
  • src/agents/bash-tools.exec.ts (modified, +2/-1)
  • src/agents/transport-stream-shared.test.ts (modified, +16/-0)
  • src/agents/transport-stream-shared.ts (modified, +10/-0)
  • src/commands/doctor-legacy-config.migrations.test.ts (modified, +3/-0)
  • test/cli-json-stdout.e2e.test.ts (modified, +1/-1)
  • test/scripts/package-acceptance-workflow.test.ts (modified, +3/-0)
  • test/scripts/test-live-shard.test.ts (modified, +5/-1)

PR #73212: fix(exec): avoid empty running output blocks

Description (problem / solution / changelog)

Summary

  • ensure exec running updates emit (no output) instead of an empty text block
  • cover empty output, warnings-only, and normal output formatting

Fixes #73117

Tests

Changed files

  • src/agents/bash-tools.exec-runtime.test.ts (modified, +20/-0)
  • src/agents/bash-tools.exec-runtime.ts (modified, +11/-2)

Code Example

const tailText = session.tail || session.aggregated;
const warningText = opts.warnings.length ? `${opts.warnings.join("\n")}\n\n` : "";
opts.onUpdate({
  content: [{
    type: "text",
    text: warningText + (tailText || "")  // ← empty string when no output
  }],
  ...
});

---

text: warningText + (tailText || "(no output)")

---

# Any silent command with no stdout
mkdir /tmp/test-dir
grep 'nonexistent' /dev/null
RAW_BUFFERClick to expand / collapse

Summary

When an exec command produces no stdout (e.g. grep with no matches, mkdir, cp, silent git commands), the exec runtime constructs a tool_result content block with text: "". Anthropic's API rejects empty text content blocks, causing the session to error out — typically after bulk operations that include several silent commands.

Root Cause

In bash-tools.exec-runtime:

const tailText = session.tail || session.aggregated;
const warningText = opts.warnings.length ? `${opts.warnings.join("\n")}\n\n` : "";
opts.onUpdate({
  content: [{
    type: "text",
    text: warningText + (tailText || "")  // ← empty string when no output
  }],
  ...
});

When both warningText and tailText are empty, text becomes "".

Fix

text: warningText + (tailText || "(no output)")

Single-character change. Falls back to a non-empty placeholder only when the command produced no output, keeping existing behaviour for all non-empty cases.

Reproduction

# Any silent command with no stdout
mkdir /tmp/test-dir
grep 'nonexistent' /dev/null

Run several in sequence in a session — subsequent API call fails with content block validation error.

Environment

  • OpenClaw v2026.4.11
  • Provider: Anthropic (amazon-bedrock)
  • Surface: telegram direct

extent analysis

TL;DR

Modify the bash-tools.exec-runtime to return a non-empty string when the exec command produces no stdout.

Guidance

  • Update the text assignment in bash-tools.exec-runtime to use a fallback value when tailText is empty, as shown in the proposed fix: text: warningText + (tailText || "(no output)").
  • Verify the fix by running silent commands in sequence and checking that the API call no longer fails with a content block validation error.
  • Test the fix with various commands that produce no stdout, such as mkdir, cp, and grep with no matches.
  • Ensure that the fix does not introduce any regressions for commands that produce output.

Example

const tailText = session.tail || session.aggregated;
const warningText = opts.warnings.length? `${opts.warnings.join("\n")}\n\n` : "";
opts.onUpdate({
  content: [{
    type: "text",
    text: warningText + (tailText || "(no output)")  // fallback to non-empty string
  }],
 ...
});

Notes

The proposed fix assumes that the bash-tools.exec-runtime code is modifiable. If this is not the case, alternative workarounds may be necessary.

Recommendation

Apply the workaround by modifying the bash-tools.exec-runtime code to use a fallback value when tailText is empty, as this is a targeted fix that addresses the specific issue with empty text content blocks.

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