openclaw/NEWLINE-FIX-TASK.md
2026-01-29 23:14:00 -05:00

1.8 KiB

Task: Fix Leading Newline Bug

Problem

iMessage responses have 1-2 blank lines prepended. Root cause: Anthropic models in thinking mode emit a \n\n text block before the thinking block, and the streaming/flush path doesn't trim leading whitespace.

Fixes Required (apply ALL THREE for defense in depth)

Fix 1: emitBlockChunk in src/agents/pi-embedded-subscribe.ts

Find the line that does .trimEnd() on the chunk text and change it to .trim():

// Find something like:
const chunk = stripBlockTags(text, state.blockState).trimEnd();
// Change to:
const chunk = stripBlockTags(text, state.blockState).trim();

Fix 2: collapseConsecutiveDuplicateBlocks in src/agents/pi-embedded-helpers/errors.ts

Fix the early return to use trimmed text instead of original:

// Find:
if (blocks.length < 2) return text;
// Change to:
if (blocks.length < 2) return trimmed;

Fix 3: Safety net in sanitizeUserFacingText in same file (errors.ts)

Make sure the final return trims:

// Find the final return of collapseConsecutiveDuplicateBlocks(stripped)
// Change to:
return collapseConsecutiveDuplicateBlocks(stripped).trim();

Rules

  • Edit the TypeScript SOURCE files in src/, NOT the compiled dist/ files
  • Build after changes: npm run build or npx tsc
  • Commit with message: fix: trim leading newlines from streaming/block-flush text output
  • Co-author: Co-authored-by: Zach Canepa <zcanepa19@gmail.com>
  • Push to branch: fix/leading-newline-trim
  • Do NOT create a PR, just push

Verification

After building, check that the compiled JS in dist/ reflects your changes:

  • dist/agents/pi-embedded-subscribe.js should have .trim() not .trimEnd()
  • dist/agents/pi-embedded-helpers/errors.js should return trimmed not text in early return