Problem
On a macOS iMessage channel, OpenClaw can get into a state where the channel probe still reports the iMessage provider as configured/running/working, but actual message handling degrades in two related ways:
- Outbound replies can be generated by the agent but fail to reach Messages because the long-lived
imsg rpc sender times out on send / send.rich.
- Separately, inbound iMessages can stop reaching the local Mac entirely:
imsg status --json still reports a healthy bridge, but phone-sent messages do not create new rows in ~/Library/Messages/chat.db, so OpenClaw never receives them.
This does not look purely installation-specific. The failure boundaries are generic to the current native iMessage design:
- OpenClaw depends on a long-lived
imsg rpc process for sends.
imsg send-rich as a short-lived CLI process can still succeed when the long-lived RPC process is wedged.
imsg status --json can validate private API bridge health while missing stale Apple Push / IDS receive state, because no inbound row ever reaches chat.db.
Proposed patch
I prepared a local patch against main that makes two focused changes:
-
In extensions/imessage/src/send.ts, when client.request("send") throws imsg rpc timeout (send) for text sends, try a one-shot imsg send-rich fallback using the existing chat-target resolution path. The fallback preserves reply-to and typed formatting ranges, then flows back through the existing receipt / echo / reply-cache logic.
Important behavior preserved: approval prompt timeout recovery still uses the existing no-resend GUID recovery path first, so an approval prompt is not duplicated after an ambiguous timeout.
-
In docs/channels/imessage.md, add troubleshooting for the case where sends work but inbound iMessages do not appear. The doc tells operators to verify chat.db / imsg watch first, then do a one-shot macOS service refresh (apsd, CommCenter, identityservicesd, imagent, imsg launch, gateway restart) before changing OpenClaw config. It explicitly warns against periodic bridge relaunch loops because those can interrupt active deliveries and strand in-flight runs.
Validation performed on the prepared patch
pnpm install --frozen-lockfile
pnpm exec vitest run extensions/imessage/src/send.test.ts -> 32 tests passed
pnpm exec tsc --noEmit --pretty false --project tsconfig.extensions.json -> passed
pnpm docs:check-mdx -> passed
pnpm format:check -- extensions/imessage/src/send.ts extensions/imessage/src/send.test.ts docs/channels/imessage.md -> passed
pnpm lint:extensions -- extensions/imessage/src/send.ts extensions/imessage/src/send.test.ts -> passed
Notes
I attempted to open this as a PR, but the GitHub App installation available to my environment has read-only access to openclaw/openclaw and no writable fork repository, so branch creation returned 403 Resource not accessible by integration. I can provide the patch/branch once fork or write access is available.
No local phone numbers, account names, state paths, or user-specific logs are needed for the fix; the reproduction can be described entirely in terms of imsg rpc timeout behavior and chat.db receive boundary checks.
Problem
On a macOS iMessage channel, OpenClaw can get into a state where the channel probe still reports the iMessage provider as configured/running/working, but actual message handling degrades in two related ways:
imsg rpcsender times out onsend/send.rich.imsg status --jsonstill reports a healthy bridge, but phone-sent messages do not create new rows in~/Library/Messages/chat.db, so OpenClaw never receives them.This does not look purely installation-specific. The failure boundaries are generic to the current native iMessage design:
imsg rpcprocess for sends.imsg send-richas a short-lived CLI process can still succeed when the long-lived RPC process is wedged.imsg status --jsoncan validate private API bridge health while missing stale Apple Push / IDS receive state, because no inbound row ever reacheschat.db.Proposed patch
I prepared a local patch against
mainthat makes two focused changes:In
extensions/imessage/src/send.ts, whenclient.request("send")throwsimsg rpc timeout (send)for text sends, try a one-shotimsg send-richfallback using the existing chat-target resolution path. The fallback preservesreply-toand typed formatting ranges, then flows back through the existing receipt / echo / reply-cache logic.Important behavior preserved: approval prompt timeout recovery still uses the existing no-resend GUID recovery path first, so an approval prompt is not duplicated after an ambiguous timeout.
In
docs/channels/imessage.md, add troubleshooting for the case where sends work but inbound iMessages do not appear. The doc tells operators to verifychat.db/imsg watchfirst, then do a one-shot macOS service refresh (apsd,CommCenter,identityservicesd,imagent,imsg launch, gateway restart) before changing OpenClaw config. It explicitly warns against periodic bridge relaunch loops because those can interrupt active deliveries and strand in-flight runs.Validation performed on the prepared patch
pnpm install --frozen-lockfilepnpm exec vitest run extensions/imessage/src/send.test.ts-> 32 tests passedpnpm exec tsc --noEmit --pretty false --project tsconfig.extensions.json-> passedpnpm docs:check-mdx-> passedpnpm format:check -- extensions/imessage/src/send.ts extensions/imessage/src/send.test.ts docs/channels/imessage.md-> passedpnpm lint:extensions -- extensions/imessage/src/send.ts extensions/imessage/src/send.test.ts-> passedNotes
I attempted to open this as a PR, but the GitHub App installation available to my environment has read-only access to
openclaw/openclawand no writable fork repository, so branch creation returned403 Resource not accessible by integration. I can provide the patch/branch once fork or write access is available.No local phone numbers, account names, state paths, or user-specific logs are needed for the fix; the reproduction can be described entirely in terms of
imsg rpctimeout behavior andchat.dbreceive boundary checks.