{"record":{"id":"6c9efbb26ada74dd","repo":"tinyhumansai/openhuman","slug":"learning-rebuild-cache-rebuild-failed-e","errorCode":null,"errorMessage":"learning_rebuild_cache: rebuild failed: {e:#}","messagePattern":"learning_rebuild_cache: rebuild failed: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/openhuman/agent/learning/tools.rs","lineNumber":435,"sourceCode":"    fn parameters_schema(&self) -> serde_json::Value {\n        json!({ \"type\": \"object\", \"properties\": {} })\n    }\n\n    fn permission_level(&self) -> PermissionLevel {\n        PermissionLevel::Execute\n    }\n\n    async fn execute(&self, _args: serde_json::Value) -> anyhow::Result<ToolResult> {\n        log::debug!(\"[tool][learning] rebuild_cache invoked\");\n        let cache = get_cache()?;\n        let detector = StabilityDetector::new(cache);\n        let now = SystemTime::now()\n            .duration_since(UNIX_EPOCH)\n            .map(|d| d.as_secs_f64())\n            .unwrap_or(0.0);\n        let outcome = detector\n            .rebuild(now)\n            .map_err(|e| anyhow::anyhow!(\"learning_rebuild_cache: rebuild failed: {e:#}\"))?;\n        Ok(ToolResult::success(serde_json::to_string(&json!({\n            \"added\": outcome.added,\n            \"evicted\": outcome.evicted,\n            \"kept\": outcome.kept,\n            \"total_size\": outcome.total_size,\n        }))?))\n    }\n}\n\n/// Reset the facet cache (delete all auto facets, keep pinned). Default-OFF.\npub struct LearningResetCacheTool;\n\n#[async_trait]\nimpl Tool for LearningResetCacheTool {\n    fn name(&self) -> &str {\n        \"learning_reset_cache\"\n    }\n","sourceCodeStart":417,"sourceCodeEnd":453,"githubUrl":"https://github.com/tinyhumansai/openhuman/blob/a221052e0df5b1f7598fceba7329fd1af95d6699/src/openhuman/agent/learning/tools.rs#L417-L453","documentation":"Thrown by learning_rebuild_cache when StabilityDetector::rebuild(now) fails. rebuild() recomputes facet stability from the accumulated evidence/candidate buffer and rewrites the user_profile table (adding, evicting, and keeping rows, respecting class budgets and pin protection) — a multi-row write cycle, so any store error mid-cycle aborts the whole rebuild. It is the heavyweight stability cycle, default-OFF alongside the other mutators.","triggerScenarios":"Invoking learning_rebuild_cache while pin/update/forget/reset tools or reflection persistence write the same table (lock contention aborts the transaction); disk full partway through the rewrite; corrupted evidence/facet rows tripping deserialization inside the detector.","commonSituations":"Agent-triggered rebuild overlapping a scheduled stability cycle; rebuild on a nearly-full disk leaving the cache partially rewritten; concurrent UI learning RPC calls.","solutions":["Ensure no other learning mutator is in flight, then retry the rebuild — it is designed as a full recompute, so a partial outcome is safe to redo","Check learning_cache_stats afterwards to see the resulting row counts","Free disk space / verify the workspace DB if the error chain shows I/O rather than lock errors","If it fails deterministically, capture the {e:#} chain — a deserialization error on a specific row points at data corruption needing a reset_cache"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Rebuild is a full recompute — safe to re-run, but check store health first:\ntool_exec(\"learning_cache_stats\", json!({})).await?; // errors => defer the rebuild","typeGuard":null,"tryCatchPattern":"match tool_exec(\"learning_rebuild_cache\", json!({})).await {\n    Ok(out) => log::info!(\"rebuild added/evicted/kept: {out}\"),\n    Err(e) => {\n        log::warn!(\"rebuild failed: {e:#}\");\n        // leave cache as-is; it is still the last consistent snapshot — retry later when idle\n    }\n}","preventionTips":["Run rebuilds when no other learning mutator or reflection persist is active","A failed rebuild leaves the previous cache intact by design — do not 'fix' it with reset_cache unless rows are corrupted","Budget for it: it rewrites the whole user_profile table"],"tags":["rust","sqlite","learning","stability","agent-tools"],"backgroundTag":null,"analyzedSha":"a221052e0df5b1f7598fceba7329fd1af95d6699","analyzedAt":"2026-08-16T12:47:06.542Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}