Bug
Version: 2026.4.1 (da64a97)
Channel: iMessage (via imsg CLI)
Description
Outbound iMessage DM replies echo back as new inbound messages, creating a feedback loop. The echo detection system exists but fails to catch these because the conversation is misclassified as a "self-chat."
Root Cause
In monitor-provider (~line 909), the self-chat detection logic:
const isSelfChat = !isGroup && chatIdentifier != null
&& normalizeIMessageHandle(sender) === normalizeIMessageHandle(chatIdentifier);
In a normal DM, imsg reports sender as the peer handle (e.g. +1XXXXXXXXXX) regardless of message direction. The chatIdentifier for that DM is also the peer handle. So sender === chatIdentifier is always true, and isSelfChat is always true for all DMs.
This matters because when is_from_me: true + isSelfChat: true, the code enters the self-chat echo cache path (4s text TTL) instead of the normal is_from_me instant-drop path. Once the 4s cache expires, subsequent echoes slip through.
Expected Behavior
For a normal DM (not actually messaging yourself), is_from_me: true messages should be dropped immediately via the "from me" reason — the else return { kind: "drop", reason: "from me" } branch.
Suggested Fix
The isSelfChat check should also require that the chat is genuinely a self-chat (user messaging their own handle), not just that sender matches chatIdentifier. For example, comparing against the local account handle, or checking if destination_caller_id matches sender.
Reproduction
- Configure iMessage channel with
dmPolicy: allowlist, allowFrom: ["+1XXXXXXXXXX"]
- Send any message from that number
- Agent replies via
imsg send
- Outbound reply appears in
imsg watch as is_from_me: true, sender: +1XXXXXXXXXX
sender === chatIdentifier → classified as self-chat → echo cache used instead of instant drop
- After 4s TTL, echoes start looping
Workaround
Disable iMessage channel until patched.
Bug
Version: 2026.4.1 (da64a97)
Channel: iMessage (via
imsgCLI)Description
Outbound iMessage DM replies echo back as new inbound messages, creating a feedback loop. The echo detection system exists but fails to catch these because the conversation is misclassified as a "self-chat."
Root Cause
In
monitor-provider(~line 909), the self-chat detection logic:In a normal DM,
imsgreportssenderas the peer handle (e.g.+1XXXXXXXXXX) regardless of message direction. ThechatIdentifierfor that DM is also the peer handle. Sosender === chatIdentifieris always true, andisSelfChatis always true for all DMs.This matters because when
is_from_me: true+isSelfChat: true, the code enters the self-chat echo cache path (4s text TTL) instead of the normalis_from_meinstant-drop path. Once the 4s cache expires, subsequent echoes slip through.Expected Behavior
For a normal DM (not actually messaging yourself),
is_from_me: truemessages should be dropped immediately via the"from me"reason — theelse return { kind: "drop", reason: "from me" }branch.Suggested Fix
The
isSelfChatcheck should also require that the chat is genuinely a self-chat (user messaging their own handle), not just that sender matches chatIdentifier. For example, comparing against the local account handle, or checking ifdestination_caller_idmatches sender.Reproduction
dmPolicy: allowlist,allowFrom: ["+1XXXXXXXXXX"]imsg sendimsg watchasis_from_me: true, sender: +1XXXXXXXXXXsender === chatIdentifier→ classified as self-chat → echo cache used instead of instant dropWorkaround
Disable iMessage channel until patched.