Description
In a self-chat scenario (Mac's iMessage handle matches the DM contact), the echo cache fails to detect reflected bot messages due to a Unicode replacement character (U+FFFD / �) prepended during attributedBody text extraction.
Steps to Reproduce
- Set up iMessage channel where the Mac's Apple ID phone number matches the DM contact's number (genuine self-chat)
- Send a message to the bot
- Bot replies via AppleScript → message stored in
chat.db with text=NULL, content only in attributedBody
imsg extracts text from attributedBody, which prepends U+FFFD (\xEF\xBF\xBD)
- Echo cache stored
"Hello" but reflected message arrives as "\uFFFD Hello" → no match → message processed again → infinite echo loop
Evidence
-- Bot messages have text=NULL, content in attributedBody only
SELECT ROWID, is_from_me, text IS NOT NULL as has_text, attributedBody IS NOT NULL as has_body
FROM message WHERE ROWID >= 2665;
-- is_from_me=true (bot): has_text=0, has_body=1
-- is_from_me=false (user): has_text=1, has_body=1
The normalizeEchoTextKey() function in monitor-provider only does .replace(/\r\n?/g, "\n").trim() — it does not strip U+FFFD characters.
Proposed Fix
In normalizeEchoTextKey(), strip U+FFFD before comparison:
function normalizeEchoTextKey(text: string): string | null {
if (!text) return null;
const normalized = text.replace(/\uFFFD/g, '').replace(/\r\n?/g, '\n').trim();
return normalized || null;
}
Alternatively, the inbound message text extraction in imsg could strip U+FFFD when parsing attributedBody.
Environment
- OpenClaw: 2026.4.2
- imsg: 0.4.0
- macOS (Darwin 24.3.0 arm64)
- iMessage channel with
dmPolicy: pairing
Workaround Attempted
Added responsePrefix: "🐙" to iMessage config — does not help because the U+FFFD breaks text matching regardless of prefix content.
Description
In a self-chat scenario (Mac's iMessage handle matches the DM contact), the echo cache fails to detect reflected bot messages due to a Unicode replacement character (U+FFFD /
�) prepended duringattributedBodytext extraction.Steps to Reproduce
chat.dbwithtext=NULL, content only inattributedBodyimsgextracts text fromattributedBody, which prepends U+FFFD (\xEF\xBF\xBD)"Hello"but reflected message arrives as"\uFFFD Hello"→ no match → message processed again → infinite echo loopEvidence
The
normalizeEchoTextKey()function inmonitor-provideronly does.replace(/\r\n?/g, "\n").trim()— it does not strip U+FFFD characters.Proposed Fix
In
normalizeEchoTextKey(), strip U+FFFD before comparison:Alternatively, the inbound message text extraction in
imsgcould strip U+FFFD when parsingattributedBody.Environment
dmPolicy: pairingWorkaround Attempted
Added
responsePrefix: "🐙"to iMessage config — does not help because the U+FFFD breaks text matching regardless of prefix content.