Skip to content

iMessage: duplicate message delivery when processing batched/queued messages #25192

@BCofSD

Description

@BCofSD

Summary

When multiple iMessage messages arrive while the agent is busy and are processed as a queued batch ("Queued messages while agent was busy"), the iMessage channel delivers the single response multiple times — once per queued message in the batch.

Observed Behavior

Gateway log shows 6 delivered reply events firing within 362ms for a single agent run:

07:33:30.530Z — imessage: delivered reply to imessage:+15039278787
07:33:30.619Z — imessage: delivered reply to imessage:+15039278787
07:33:30.689Z — imessage: delivered reply to imessage:+15039278787
07:33:30.758Z — imessage: delivered reply to imessage:+15039278787
07:33:30.828Z — imessage: delivered reply to imessage:+15039278787
07:33:30.892Z — imessage: delivered reply to imessage:+15039278787

Run context:

Also seen with 2 deliveries within ~75ms for smaller batches (2 queued messages → 2 sends).

Steps to Reproduce

  1. Have an active iMessage conversation
  2. Send 2+ messages in quick succession while agent is processing a previous task
  3. Agent receives them as a "Queued messages while agent was busy" batch
  4. Agent produces one response
  5. iMessage channel delivers it N times (where N appears to correlate with queue depth or internal listeners)

Expected Behavior

One response delivered once per agent run, regardless of how many messages were in the inbound queue.

Environment

  • OpenClaw version: 2026.2.22-2
  • Channel: imessage
  • OS: macOS (Darwin 25.3.0 arm64)
  • Node: v22.22.0
  • Model: anthropic/claude-sonnet-4-6, thinking=low

Likely Cause

Race condition in the queued-message batch delivery path. Hypothesis: when N messages are queued and coalesced into a single agent run, the completion handler may be registered N times (once per queued message), each firing independently on run completion.

Suggest adding a deduplication guard in the iMessage delivery path keyed on runId — first delivery wins, subsequent duplicate deliveries within a short window (e.g., 500ms) for the same runId are dropped.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions