{"record":{"id":"933c91e95e91e1f4","repo":"tinyhumansai/openhuman","slug":"core-rpc","errorCode":null,"errorMessage":"core rpc {}: {}","messagePattern":"core rpc (.+?): (.+?)","errorType":"http","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"app/src-tauri/src/imessage_scanner/mod.rs","lineNumber":452,"sourceCode":"            \"key\": key,\n            \"title\": format!(\"Messages — {} — {}\", chat_id, day),\n            \"content\": transcript,\n            \"source_type\": \"imessage\",\n            \"tags\": [\"chat\", \"imessage\"],\n            \"metadata\": {\n                \"chat_identifier\": chat_id,\n                \"day\": day,\n                \"source\": \"imessage\"\n            },\n            \"category\": \"chat\"\n        }\n    });\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\n    if !res.status().is_success() {\n        anyhow::bail!(\"core rpc {}: {}\", res.status(), res.text().await?);\n    }\n\n    log::info!(\"[imessage] memory upsert ok key={}\", key);\n    Ok(())\n}\n\n// Non-macOS stub so the rest of the app compiles unchanged.\n#[cfg(not(target_os = \"macos\"))]\npub struct ScannerRegistry;\n\n#[cfg(not(target_os = \"macos\"))]\nimpl ScannerRegistry {\n    pub fn new() -> Self {\n        Self\n    }\n    pub fn shutdown(&self) {}\n}\n","sourceCodeStart":434,"sourceCodeEnd":470,"githubUrl":"https://github.com/tinyhumansai/openhuman/blob/a221052e0df5b1f7598fceba7329fd1af95d6699/app/src-tauri/src/imessage_scanner/mod.rs#L434-L470","documentation":"The scanner's memory-upsert step POSTs an already-built memory-doc payload to the core's /rpc; a non-success status bails with `core rpc <status>: <body>`. The chat.db scan succeeded — the failure is between the Tauri shell and the local core, and the upserted day is not persisted this tick.","triggerScenarios":"Core restarted/restarting when the upsert fired (stale bearer → 401); core returned 500 while persisting memory (disk full, memory-store db lock); payload rejected by the RPC layer.","commonSituations":"App update restarting the in-process core while a scan finishes; storage pressure on the workspace; the same stale-token situations as error 292 but hitting the write path.","solutions":["Read the body in the error — it is the core's answer and names the real problem","If 401-after-restart: the next periodic tick re-authenticates; restart the app if it persists","Resolve storage-side causes the core reports (free disk, clear db locks)","Rely on keyed, idempotent upserts: re-running the scan replays the missed day safely"],"exampleFix":"// before\nlet res = req.json(&body).send().await?;\nif !res.status().is_success() {\n    anyhow::bail!(\"core rpc {}: {}\", res.status(), res.text().await?);\n}\n\n// after — one bounded retry on 5xx before giving up the tick\nlet send = |b: serde_json::Value| async { crate::core_rpc::apply_auth(http_client().post(&url))\n    .map_err(anyhow::Error::msg)?.json(&b).send().await };\nlet mut res = send(body.clone()).await?;\nif res.status().as_u16() >= 500 { res = send(body).await?; }\nif !res.status().is_success() {\n    anyhow::bail!(\"core rpc {}: {}\", res.status(), res.text().await?);\n}","handlingStrategy":"retry","validationCode":"// pre-flight the core before a batch of upserts\nif !core_rpc_reachable(&url).await {\n    log::warn!(\"[imessage] core unreachable; deferring memory upsert to next tick\");\n    return Ok(());\n}","typeGuard":null,"tryCatchPattern":"for attempt in 0..2 {\n    match upsert_memory_doc(&url, &body).await {\n        Ok(()) => break,\n        Err(e) if attempt == 0 && e.to_string().starts_with(\"core rpc 5\") => continue,\n        Err(e) if e.to_string().starts_with(\"core rpc 401\") => {\n            log::warn!(\"[imessage] stale auth; next tick re-authenticates\"); break;\n        }\n        Err(e) => return Err(e),\n    }\n}","preventionTips":["keep upserts keyed/idempotent so retries and replays are safe","expect 401 windows around in-process core restarts; degrade, do not crash","alert on repeated per-tick upsert failures rather than one-off losses"],"tags":["jsonrpc","http","imessage","memory","retry"],"backgroundTag":null,"analyzedSha":"a221052e0df5b1f7598fceba7329fd1af95d6699","analyzedAt":"2026-08-16T12:47:06.542Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}