{"record":{"id":"f22090e64a24e1fe","repo":"zeroclaw-labs/zeroclaw","slug":"imessage-send-failed-stderr","errorCode":null,"errorMessage":"iMessage send failed: {stderr}","messagePattern":"iMessage send failed: (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/zeroclaw-channels/src/imessage.rs","lineNumber":180,"sourceCode":"        let escaped_target = escape_applescript(&message.recipient);\n\n        let script = format!(\n            r#\"tell application \"Messages\"\n    set targetService to 1st account whose service type = iMessage\n    set targetBuddy to participant \"{escaped_target}\" of targetService\n    send \"{escaped_msg}\" to targetBuddy\nend tell\"#\n        );\n\n        let output = tokio::process::Command::new(\"osascript\")\n            .arg(\"-e\")\n            .arg(&script)\n            .output()\n            .await?;\n\n        if !output.status.success() {\n            let stderr = String::from_utf8_lossy(&output.stderr);\n            anyhow::bail!(\"iMessage send failed: {stderr}\");\n        }\n\n        Ok(())\n    }\n\n    async fn listen(&self, tx: mpsc::Sender<ChannelMessage>) -> anyhow::Result<()> {\n        ::zeroclaw_log::record!(\n            INFO,\n            ::zeroclaw_log::Event::new(module_path!(), ::zeroclaw_log::Action::Note),\n            \"iMessage channel listening (AppleScript bridge)...\"\n        );\n\n        // Query the Messages SQLite database for new messages\n        // The database is at ~/Library/Messages/chat.db\n        let db_path = UserDirs::new()\n            .map(|u| u.home_dir().join(\"Library/Messages/chat.db\"))\n            .ok_or_else(|| {\n                ::zeroclaw_log::record!(","sourceCodeStart":162,"sourceCodeEnd":198,"githubUrl":"https://github.com/zeroclaw-labs/zeroclaw/blob/88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc/crates/zeroclaw-channels/src/imessage.rs#L162-L198","documentation":"IMessageChannel::send runs an osascript AppleScript that tells Messages.app to send the text; when the process exits non-zero, the captured stderr becomes the error. The AppleScript itself escaped both message and target against CWE-78 injection, so a non-zero exit is environmental: Messages.app state, AppleScript/Automation permissions, or an unreachable recipient — the stderr text carries the real reason.","triggerScenarios":"osascript exits non-zero: Messages.app not signed into an iCloud account with iMessage enabled; macOS Automation permission not granted to the process invoking osascript ('Not authorized to send Apple events to Messages'); recipient not registered with iMessage; Messages.app not running/first-run dialogs pending.","commonSituations":"Fresh mac that never opened Messages.app; zeroclaw launched from a terminal or launchd agent missing in System Settings > Privacy & Security > Automation; recipient is an SMS-only number; macOS update reset TCC permissions.","solutions":["Reproduce manually to see the real AppleScript error: run the same 'tell application \"Messages\" ... send ...' snippet via osascript -e in the same terminal/session","Grant Automation permission: System Settings > Privacy & Security > Automation > [your terminal/zeroclaw] > Messages","Open Messages.app, sign into iCloud, confirm iMessage is active, and verify the recipient works from the GUI","If the target is SMS-only, route through a different channel — the AppleScript bridge only does iMessage"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"match channel.send(&msg).await {\n    Err(e) if e.to_string().contains(\"iMessage send failed\") => {\n        // e carries osascript stderr verbatim: match on 'Not authorized' (Automation perm),\n        // 'not signed in' (iCloud), or registration errors; route message to a fallback channel\n    }\n    other => other?,\n}","preventionTips":["Pre-authorize osascript: once from a terminal run any Messages AppleScript and accept the Automation prompt","Check Messages.app is signed in and the recipient is iMessage-registered before relying on this bridge","Treat stderr text as the diagnosis — reproduce the failing script manually before changing code"],"tags":["imessage","applescript","osascript","macos","permissions"],"backgroundTag":"applescript-execution-failed","analyzedSha":"88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc","analyzedAt":"2026-08-23T01:07:41.857Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}