Skip to content

iMessage echo loop: DM incorrectly classified as self-chat, bypassing echo filter #59845

Description

@mccloskey1024

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

  1. Configure iMessage channel with dmPolicy: allowlist, allowFrom: ["+1XXXXXXXXXX"]
  2. Send any message from that number
  3. Agent replies via imsg send
  4. Outbound reply appears in imsg watch as is_from_me: true, sender: +1XXXXXXXXXX
  5. sender === chatIdentifier → classified as self-chat → echo cache used instead of instant drop
  6. After 4s TTL, echoes start looping

Workaround

Disable iMessage channel until patched.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions