{"record":{"id":"8aedd948863829eb","repo":"zeroclaw-labs/zeroclaw","slug":"messages-database-not-found-at-ensure-messages","errorCode":null,"errorMessage":"Messages database not found at {}. Ensure Messages.app is set up and Full Disk Access is granted.","messagePattern":"Messages database not found at (.+?)\\. Ensure Messages\\.app is set up and Full Disk Access is granted\\.","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/zeroclaw-channels/src/imessage.rs","lineNumber":208,"sourceCode":"            \"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!(\n                    ERROR,\n                    ::zeroclaw_log::Event::new(module_path!(), ::zeroclaw_log::Action::Fail)\n                        .with_outcome(::zeroclaw_log::EventOutcome::Failure),\n                    \"Cannot find home directory\"\n                );\n                anyhow::Error::msg(\"Cannot find home directory\")\n            })?;\n\n        if !db_path.exists() {\n            anyhow::bail!(\n                \"Messages database not found at {}. Ensure Messages.app is set up and Full Disk Access is granted.\",\n                db_path.display()\n            );\n        }\n\n        // Open a persistent read-only connection instead of creating\n        // a new one on every 3-second poll cycle.\n        let path = db_path.to_path_buf();\n        let conn = tokio::task::spawn_blocking(move || -> anyhow::Result<Connection> {\n            Ok(Connection::open_with_flags(\n                &path,\n                OpenFlags::SQLITE_OPEN_READ_ONLY | OpenFlags::SQLITE_OPEN_NO_MUTEX,\n            )?)\n        })\n        .await??;\n\n        // Track the last ROWID we've seen (shuttle conn in and out)\n        let (mut conn, initial_rowid) =","sourceCodeStart":190,"sourceCodeEnd":226,"githubUrl":"https://github.com/zeroclaw-labs/zeroclaw/blob/88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc/crates/zeroclaw-channels/src/imessage.rs#L190-L226","documentation":"IMessageChannel::listen polls ~/Library/Messages/chat.db (built from the user's home dir) for inbound messages; before opening the SQLite connection it checks db_path.exists() and bails with this message when the chat database is not there. On modern macOS the chat.db is protected by TCC, so the practical causes are: Messages.app never initialized the database, or the calling process lacks Full Disk Access so the path is not even visible.","triggerScenarios":"listen() is called on a Mac where ~/Library/Messages/chat.db does not exist or is invisible to the process: fresh macOS install where Messages.app was never set up, a different user's home (UserDirs resolving elsewhere), or TCC denying Full Disk Access to the binary/terminal running zeroclaw.","commonSituations":"Headless Mac mini / CI runner where Messages.app was never opened; zeroclaw started from a launchd agent or IDE whose parent app lacks Full Disk Access; macOS upgrade re-prompting TCC consent.","solutions":["Verify the file exists: ls ~/Library/Messages/chat.db — if missing, open Messages.app once and sign in so it creates the database","Grant Full Disk Access to the app that runs zeroclaw (terminal, launchd agent, or the binary itself) under System Settings > Privacy & Security > Full Disk Access, then restart that app","Confirm HOME/user-dirs resolution points at the interactive user's home when running under a service account","Re-run listen() after granting permissions — TCC changes require restarting the granted process"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Pre-flight before listen():\nlet db = home.join(\"Library/Messages/chat.db\");\nanyhow::ensure!(\n    db.exists(),\n    \"~/Library/Messages/chat.db missing: open Messages.app once and grant Full Disk Access\"\n);","typeGuard":null,"tryCatchPattern":"if let Err(e) = channel.listen(tx).await {\n    if e.to_string().contains(\"Messages database not found\") {\n        // environment problem: prompt operator for Full Disk Access / Messages.app setup, then restart\n    }\n}","preventionTips":["Grant Full Disk Access to whatever app launches zeroclaw (terminal, launchd agent) before enabling the imessage channel","Open Messages.app and sign in once on any fresh Mac before using this channel","Re-check permissions after macOS upgrades — TCC grants sometimes reset"],"tags":["imessage","macos","full-disk-access","sqlite","file-not-found"],"backgroundTag":"file-not-found","analyzedSha":"88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc","analyzedAt":"2026-08-23T01:07:41.857Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}