fix: strip leading whitespace from sanitizeUserFacingText output#16158
Merged
Takhoffman merged 2 commits intoopenclaw:mainfrom Feb 14, 2026
Merged
fix: strip leading whitespace from sanitizeUserFacingText output#16158Takhoffman merged 2 commits intoopenclaw:mainfrom
Takhoffman merged 2 commits intoopenclaw:mainfrom
Conversation
LLM responses frequently begin with \n\n, which survives through sanitizeUserFacingText and reaches the channel as visible blank lines. Root cause: the function used trimmed text for empty-checks but returned the untrimmed 'stripped' variable. Two one-line fixes: 1. Return empty string (not whitespace-only 'stripped') for blank input 2. Apply trimStart() to the final return value Fixes the same issue as openclaw#8052 and openclaw#10612 but at the root cause (sanitizeUserFacingText) rather than scattering trimStart across multiple delivery paths.
Co-authored-by: Tak Hoffman <[email protected]>
72e2b92 to
a9db342
Compare
steipete
added a commit
that referenced
this pull request
Feb 14, 2026
steipete
added a commit
that referenced
this pull request
Feb 14, 2026
steipete
added a commit
that referenced
this pull request
Feb 14, 2026
steipete
added a commit
that referenced
this pull request
Feb 14, 2026
* fix: strip leading empty lines in sanitizeUserFacingText (#16158) (thanks @mcinteerj) * fix: strip leading empty lines in sanitizeUserFacingText (#16158) (thanks @mcinteerj) * fix: strip leading empty lines in sanitizeUserFacingText (#16158) (thanks @mcinteerj)
hamidzr
pushed a commit
to hamidzr/openclaw
that referenced
this pull request
Feb 14, 2026
…nclaw#16158) * fix: strip leading whitespace from sanitizeUserFacingText output LLM responses frequently begin with \n\n, which survives through sanitizeUserFacingText and reaches the channel as visible blank lines. Root cause: the function used trimmed text for empty-checks but returned the untrimmed 'stripped' variable. Two one-line fixes: 1. Return empty string (not whitespace-only 'stripped') for blank input 2. Apply trimStart() to the final return value Fixes the same issue as openclaw#8052 and openclaw#10612 but at the root cause (sanitizeUserFacingText) rather than scattering trimStart across multiple delivery paths. * Changelog: note sanitizeUserFacingText whitespace normalization Co-authored-by: Tak Hoffman <[email protected]> --------- Co-authored-by: Tak Hoffman <[email protected]>
hamidzr
pushed a commit
to hamidzr/openclaw
that referenced
this pull request
Feb 14, 2026
) * fix: strip leading empty lines in sanitizeUserFacingText (openclaw#16158) (thanks @mcinteerj) * fix: strip leading empty lines in sanitizeUserFacingText (openclaw#16158) (thanks @mcinteerj) * fix: strip leading empty lines in sanitizeUserFacingText (openclaw#16158) (thanks @mcinteerj)
mcinteerj
added a commit
to mcinteerj/openclaw
that referenced
this pull request
Feb 14, 2026
The block streaming delivery path (onBlockReply) bypasses sanitizeUserFacingText, so the trimStart fix from openclaw#16158/openclaw#16280 doesn't apply to users with blockStreaming enabled (the default). Adds trimStart() to the cleaned text in the block reply payload construction, consistent with the non-streaming path.
mcinteerj
added a commit
to mcinteerj/openclaw
that referenced
this pull request
Feb 14, 2026
The block streaming delivery path (onBlockReply) bypasses sanitizeUserFacingText, so the trimStart fix from openclaw#16158/openclaw#16280 doesn't apply to users with blockStreaming enabled (the default). Adds trimStart() to the cleaned text in the block reply payload construction, consistent with the non-streaming path.
mverrilli
pushed a commit
to mverrilli/openclaw
that referenced
this pull request
Feb 14, 2026
…nclaw#16158) * fix: strip leading whitespace from sanitizeUserFacingText output LLM responses frequently begin with \n\n, which survives through sanitizeUserFacingText and reaches the channel as visible blank lines. Root cause: the function used trimmed text for empty-checks but returned the untrimmed 'stripped' variable. Two one-line fixes: 1. Return empty string (not whitespace-only 'stripped') for blank input 2. Apply trimStart() to the final return value Fixes the same issue as openclaw#8052 and openclaw#10612 but at the root cause (sanitizeUserFacingText) rather than scattering trimStart across multiple delivery paths. * Changelog: note sanitizeUserFacingText whitespace normalization Co-authored-by: Tak Hoffman <[email protected]> --------- Co-authored-by: Tak Hoffman <[email protected]>
mverrilli
pushed a commit
to mverrilli/openclaw
that referenced
this pull request
Feb 14, 2026
) * fix: strip leading empty lines in sanitizeUserFacingText (openclaw#16158) (thanks @mcinteerj) * fix: strip leading empty lines in sanitizeUserFacingText (openclaw#16158) (thanks @mcinteerj) * fix: strip leading empty lines in sanitizeUserFacingText (openclaw#16158) (thanks @mcinteerj)
akoscz
pushed a commit
to akoscz/openclaw
that referenced
this pull request
Feb 15, 2026
) * fix: strip leading empty lines in sanitizeUserFacingText (openclaw#16158) (thanks @mcinteerj) * fix: strip leading empty lines in sanitizeUserFacingText (openclaw#16158) (thanks @mcinteerj) * fix: strip leading empty lines in sanitizeUserFacingText (openclaw#16158) (thanks @mcinteerj)
sebslight
pushed a commit
to mcinteerj/openclaw
that referenced
this pull request
Feb 15, 2026
The block streaming delivery path (onBlockReply) bypasses sanitizeUserFacingText, so the trimStart fix from openclaw#16158/openclaw#16280 doesn't apply to users with blockStreaming enabled (the default). Adds trimStart() to the cleaned text in the block reply payload construction, consistent with the non-streaming path.
GwonHyeok
pushed a commit
to learners-superpumped/openclaw
that referenced
this pull request
Feb 15, 2026
…nclaw#16158) * fix: strip leading whitespace from sanitizeUserFacingText output LLM responses frequently begin with \n\n, which survives through sanitizeUserFacingText and reaches the channel as visible blank lines. Root cause: the function used trimmed text for empty-checks but returned the untrimmed 'stripped' variable. Two one-line fixes: 1. Return empty string (not whitespace-only 'stripped') for blank input 2. Apply trimStart() to the final return value Fixes the same issue as openclaw#8052 and openclaw#10612 but at the root cause (sanitizeUserFacingText) rather than scattering trimStart across multiple delivery paths. * Changelog: note sanitizeUserFacingText whitespace normalization Co-authored-by: Tak Hoffman <[email protected]> --------- Co-authored-by: Tak Hoffman <[email protected]>
GwonHyeok
pushed a commit
to learners-superpumped/openclaw
that referenced
this pull request
Feb 15, 2026
) * fix: strip leading empty lines in sanitizeUserFacingText (openclaw#16158) (thanks @mcinteerj) * fix: strip leading empty lines in sanitizeUserFacingText (openclaw#16158) (thanks @mcinteerj) * fix: strip leading empty lines in sanitizeUserFacingText (openclaw#16158) (thanks @mcinteerj)
snowzlm
pushed a commit
to snowzlm/openclaw
that referenced
this pull request
Feb 15, 2026
) * fix: strip leading empty lines in sanitizeUserFacingText (openclaw#16158) (thanks @mcinteerj) * fix: strip leading empty lines in sanitizeUserFacingText (openclaw#16158) (thanks @mcinteerj) * fix: strip leading empty lines in sanitizeUserFacingText (openclaw#16158) (thanks @mcinteerj)
6 tasks
hughdidit
pushed a commit
to hughdidit/DAISy-Agency
that referenced
this pull request
Mar 1, 2026
…nclaw#16158) * fix: strip leading whitespace from sanitizeUserFacingText output LLM responses frequently begin with \n\n, which survives through sanitizeUserFacingText and reaches the channel as visible blank lines. Root cause: the function used trimmed text for empty-checks but returned the untrimmed 'stripped' variable. Two one-line fixes: 1. Return empty string (not whitespace-only 'stripped') for blank input 2. Apply trimStart() to the final return value Fixes the same issue as openclaw#8052 and openclaw#10612 but at the root cause (sanitizeUserFacingText) rather than scattering trimStart across multiple delivery paths. * Changelog: note sanitizeUserFacingText whitespace normalization Co-authored-by: Tak Hoffman <[email protected]> --------- Co-authored-by: Tak Hoffman <[email protected]> (cherry picked from commit 3881af5) # Conflicts: # CHANGELOG.md
hughdidit
pushed a commit
to hughdidit/DAISy-Agency
that referenced
this pull request
Mar 1, 2026
) * fix: strip leading empty lines in sanitizeUserFacingText (openclaw#16158) (thanks @mcinteerj) * fix: strip leading empty lines in sanitizeUserFacingText (openclaw#16158) (thanks @mcinteerj) * fix: strip leading empty lines in sanitizeUserFacingText (openclaw#16158) (thanks @mcinteerj) (cherry picked from commit 50a6e0e) # Conflicts: # CHANGELOG.md
hughdidit
pushed a commit
to hughdidit/DAISy-Agency
that referenced
this pull request
Mar 3, 2026
…nclaw#16158) * fix: strip leading whitespace from sanitizeUserFacingText output LLM responses frequently begin with \n\n, which survives through sanitizeUserFacingText and reaches the channel as visible blank lines. Root cause: the function used trimmed text for empty-checks but returned the untrimmed 'stripped' variable. Two one-line fixes: 1. Return empty string (not whitespace-only 'stripped') for blank input 2. Apply trimStart() to the final return value Fixes the same issue as openclaw#8052 and openclaw#10612 but at the root cause (sanitizeUserFacingText) rather than scattering trimStart across multiple delivery paths. * Changelog: note sanitizeUserFacingText whitespace normalization Co-authored-by: Tak Hoffman <[email protected]> --------- Co-authored-by: Tak Hoffman <[email protected]> (cherry picked from commit 3881af5) # Conflicts: # CHANGELOG.md # src/agents/pi-embedded-helpers/errors.ts
hughdidit
pushed a commit
to hughdidit/DAISy-Agency
that referenced
this pull request
Mar 3, 2026
) * fix: strip leading empty lines in sanitizeUserFacingText (openclaw#16158) (thanks @mcinteerj) * fix: strip leading empty lines in sanitizeUserFacingText (openclaw#16158) (thanks @mcinteerj) * fix: strip leading empty lines in sanitizeUserFacingText (openclaw#16158) (thanks @mcinteerj) (cherry picked from commit 50a6e0e) # Conflicts: # CHANGELOG.md
zooqueen
pushed a commit
to hanzoai/bot
that referenced
this pull request
Mar 6, 2026
…nclaw#16158) * fix: strip leading whitespace from sanitizeUserFacingText output LLM responses frequently begin with \n\n, which survives through sanitizeUserFacingText and reaches the channel as visible blank lines. Root cause: the function used trimmed text for empty-checks but returned the untrimmed 'stripped' variable. Two one-line fixes: 1. Return empty string (not whitespace-only 'stripped') for blank input 2. Apply trimStart() to the final return value Fixes the same issue as openclaw#8052 and openclaw#10612 but at the root cause (sanitizeUserFacingText) rather than scattering trimStart across multiple delivery paths. * Changelog: note sanitizeUserFacingText whitespace normalization Co-authored-by: Tak Hoffman <[email protected]> --------- Co-authored-by: Tak Hoffman <[email protected]>
zooqueen
pushed a commit
to hanzoai/bot
that referenced
this pull request
Mar 6, 2026
) * fix: strip leading empty lines in sanitizeUserFacingText (openclaw#16158) (thanks @mcinteerj) * fix: strip leading empty lines in sanitizeUserFacingText (openclaw#16158) (thanks @mcinteerj) * fix: strip leading empty lines in sanitizeUserFacingText (openclaw#16158) (thanks @mcinteerj)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
LLM responses frequently begin with
\n\n, causing visible blank lines at the top of messages on WhatsApp (and other channels). This fixes the root cause insanitizeUserFacingTextrather than scatteringtrimStart()across multiple delivery paths.lobster-biscuit
Repro Steps
\n\n(common with Claude Opus 4.6)Root Cause
sanitizeUserFacingTextinsrc/agents/pi-embedded-helpers/errors.tsusestrimmedfor empty-checks but returns the untrimmedstrippedvariable:Fix
Two one-line changes:
""instead of whitespace-onlystripped.trimStart()aftercollapseConsecutiveDuplicateBlocksThis is the single funnel point — all reply paths (auto-reply, heartbeat, outbound) flow through
sanitizeUserFacingTextvianormalizeReplyPayload, so the fix applies universally without touching delivery code.Behavior Changes
\nor\n\nwill have that whitespace stripped before delivery""instead of the whitespace stringCodebase and GitHub Search
normalizeReplyPayloadinsrc/auto-reply/reply/normalize-reply.tscallssanitizeUserFacingText— confirmed single funnel pointTests
4 new test cases added to
pi-embedded-helpers.sanitizeuserfacingtext.e2e.test.ts:All 15 tests pass (11 existing + 4 new).
Manual Testing
Tested by observing WhatsApp message output before/after the change — leading blank lines no longer appear.
Sign-Off
Greptile Overview
Greptile Summary
Fixes leading whitespace in LLM responses by modifying
sanitizeUserFacingTextinsrc/agents/pi-embedded-helpers/errors.ts. The function now returns an empty string for whitespace-only input and strips leading whitespace from the final output using.trimStart(). This addresses the root cause of blank lines appearing at the top of WhatsApp messages when Claude Opus 4.6 responses begin with\n\n.Changes:
""instead of whitespace-only string when input is empty after trimming.trimStart()to the final return value aftercollapseConsecutiveDuplicateBlocksThe fix is well-targeted at the single funnel point where all reply paths flow through
normalizeReplyPayload, avoiding the need to patch multiple delivery paths.Confidence Score: 5/5
.trimStart()uniformly to all non-error output paths without affecting error message formatting. All existing tests continue to pass, and the new tests verify the specific behavior changes.Last reviewed commit: efdcf74