{"record":{"id":"990f7c380ebaecd4","repo":"tinyhumansai/openhuman","slug":"config-get-http","errorCode":null,"errorMessage":"config_get http {}","messagePattern":"config_get http (.+?)","errorType":"http","errorClass":"anyhow::Error","httpStatus":null,"severity":"warning","filePath":"app/src-tauri/src/imessage_scanner/mod.rs","lineNumber":208,"sourceCode":"///\n/// Returns:\n/// - `Ok(Some(allowed_contacts))` when iMessage is connected (allow-list may\n///   be empty = \"all chats\")\n/// - `Ok(None)` when iMessage is not connected / config absent\n/// - `Err(_)` on transport or parse errors (caller should retry next tick)\n#[cfg(target_os = \"macos\")]\nasync fn fetch_imessage_gate() -> anyhow::Result<Option<Vec<String>>> {\n    let url = crate::core_rpc::core_rpc_url_value();\n    let body = json!({\n        \"jsonrpc\": \"2.0\",\n        \"id\": 1,\n        \"method\": \"openhuman.config_get\",\n        \"params\": {}\n    });\n    let req = crate::core_rpc::apply_auth(http_client().post(&url)).map_err(anyhow::Error::msg)?;\n    let res = req.json(&body).send().await?;\n    if !res.status().is_success() {\n        anyhow::bail!(\"config_get http {}\", res.status());\n    }\n    let v: serde_json::Value = res.json().await?;\n    // JSON-RPC envelope is `{\"result\": {\"logs\": [...], \"result\": <RpcOutcome body>}}`\n    // so the config lives at `/result/result/config/...`, not `/result/config/...`.\n    let imessage = v\n        .pointer(\"/result/result/config/channels_config/imessage\")\n        .cloned();\n    let Some(imessage) = imessage else {\n        return Ok(None);\n    };\n    if imessage.is_null() {\n        return Ok(None);\n    }\n    let contacts = imessage\n        .get(\"allowed_contacts\")\n        .and_then(|c| c.as_array())\n        .map(|arr| {\n            arr.iter()","sourceCodeStart":190,"sourceCodeEnd":226,"githubUrl":"https://github.com/tinyhumansai/openhuman/blob/a221052e0df5b1f7598fceba7329fd1af95d6699/app/src-tauri/src/imessage_scanner/mod.rs#L190-L226","documentation":"fetch_imessage_gate() POSTs openhuman.config_get to the core's /rpc (auth applied via core_rpc::apply_auth) to read channels_config.imessage before a scan tick (called from tick.rs); a non-success HTTP status bails with `config_get http <status>`. The scan's SQLite side is fine — this is shell→core communication failing.","triggerScenarios":"401 from a stale per-launch bearer (the core restarted and got a new in-memory token while the scanner tick was in flight); core mid-shutdown during app update; connection-level failure surfaced as a status error; 500 from the core while serializing config.","commonSituations":"Core auto-restarted after an update while a tick ran; debugging with OPENHUMAN_CORE_REUSE_EXISTING=1 against a core started with a different token; core crashed and the shell has not noticed yet.","solutions":["Restart the app so the shell re-hands the fresh in-memory bearer to the scanner","If pointing at an external core, make sure the token matches that core (OPENHUMAN_CORE_TOKEN / core.token)","Check core logs at the timestamp to see the actual status and body","Treat it as transient: ticks are periodic and self-heal on the next cycle once auth is aligned"],"exampleFix":"// before (imessage_scanner/tick.rs)\nlet gate = super::fetch_imessage_gate().await?;   // aborts the whole tick\n\n// after — degrade this optional-feature fetch instead of failing the tick\nlet gate = match super::fetch_imessage_gate().await {\n    Ok(g) => g,\n    Err(e) => { log::warn!(\"[imessage] gate unavailable ({e}); skipping tick\"); return Ok(()); }\n};","handlingStrategy":"retry","validationCode":"async fn core_healthy(base: &str) -> bool {\n    let health = format!(\"{}/health\", base.trim_end_matches(\"/rpc\"));\n    crate::core_rpc::apply_auth(http_client().get(health)).send().await\n        .map(|r| r.status().is_success()).unwrap_or(false)\n}\n// skip the gate fetch (and the scan) when the core is mid-restart","typeGuard":null,"tryCatchPattern":"let gate = match fetch_imessage_gate().await {\n    Ok(g) => g,\n    Err(e) => {\n        log::warn!(\"[imessage] gate fetch failed ({e}); retrying next tick\");\n        return Ok(());   // periodic tick replays this for free\n    }\n};","preventionTips":["make scanner ticks periodic and idempotent so a failed tick self-heals","re-fetch the token via the core_rpc_token command when 401s appear after core restarts","log the HTTP status distinctly for triage"],"tags":["jsonrpc","http","imessage","auth","tauri"],"backgroundTag":null,"analyzedSha":"a221052e0df5b1f7598fceba7329fd1af95d6699","analyzedAt":"2026-08-16T12:47:06.542Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}