Skip to content

[Bug]: Bash ANSI sanitization leaks sequences split across output chunks #103668

Description

@steipete

Bug type

Behavior bug (incorrect output/state without crash)

Beta release blocker

No

Summary

Bash output sanitization leaks ANSI/OSC fragments when a complete control sequence is split across process-output chunks.

Steps to reproduce

  1. On current main, use the executeBashWithOperations path with an operation that emits A\u001B]0;title in one onData callback and \u0007B in the next.
  2. Join the streamed output chunks or inspect the final BashResult.output.
  3. Compare that output with sanitizing the joined input A\u001B]0;title\u0007B once.

Equivalent source probe:

const transform = (text: string) => sanitizeBinaryOutput(stripAnsiSequences(text));
const chunks = ["A\u001B]0;title", "\u0007B"];
console.log({
  joined: transform(chunks.join("")),
  split: chunks.map(transform).join(""),
});

Expected behavior

Sanitization is invariant under process-output chunking: the joined streamed output and final result are both AB, matching whole-input sanitization.

Actual behavior

Whole-input sanitization returns AB, while per-chunk sanitization returns Aitle\u0007B. Other valid splits also leak fragments:

  • ESC OSC ... ESC ST -> Aitle\u001B\\B
  • C1 OSC + C1 ST -> A\u009D0;title\u009CB
  • C1 OSC + ESC ST -> A\u009D0;title\u001B\\B
  • ESC or C1 CSI split before final m -> AmB

OpenClaw version

main at 4cc5304178

Operating system

Linux

Install method

Source checkout

Model

N/A

Provider / routing chain

N/A

Additional provider/model setup details

N/A

Logs

ESC OSC + BEL: joined=AB split=Aitle\\x07B
ESC OSC + ESC-ST: joined=AB split=Aitle\\x1b\\B
C1 OSC + C1-ST: joined=AB split=A\\x9d0;title\\x9cB
C1 OSC + ESC-ST: joined=AB split=A\\x9d0;title\\x1b\\B
ESC CSI: joined=AB split=AmB
C1 CSI: joined=AB split=AmB

Screenshots, recordings, and evidence

The deterministic source-level split probe above is the evidence; no visual asset is required.

Impact and severity

  • Affected: agent bash execution streaming, returned output, and sanitized spill files.
  • Severity: moderate output-integrity defect.
  • Frequency: deterministic when the OS/process splits an ANSI sequence across callbacks.
  • Consequence: control-sequence payloads or fragments can reach agent/session context and streamed tool output instead of being removed.

Additional information

executeBashWithOperations configures OutputAccumulator to run sanitizeBinaryOutput(stripAnsiSequences(text)) independently for each decoded callback. Both functions are whole-string transforms, so neither can retain an incomplete ESC/CSI/OSC state for the next chunk. The canonical fix needs an incremental terminal-core scanner or an explicitly stateful accumulator transform with bounded final handling for unterminated sequences; concatenating all output before sanitization would regress streaming and memory behavior. No matching OpenClaw issue or PR was found by searches for ANSI output chunks, split ANSI sequences, OSC chunk boundaries, stateful ANSI sanitization, and bash output sanitization.

Metadata

Metadata

Assignees

Labels

P2Normal backlog priority with limited blast radius.agentsAgent runtime and toolingbugSomething isn't workingmaintainerMaintainer-authored PR

Type

No type

Fields

Priority

None yet

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions