tinyhumansai/openhuman · error

learning_reset_cache: {e:#}

Error message

learning_reset_cache: {e:#}

What it means

Thrown by learning_reset_cache when FacetCache::list_all() fails before any deletion happens. reset_cache is the Dangerous-permission, default-OFF tool that deletes every non-Pinned facet; it must first enumerate all rows, and that read failed. Note the asymmetry: only list_all errors surface — per-row delete failures are swallowed by unwrap_or(false) and merely count as not-deleted.

Source

Thrown at src/openhuman/agent/learning/tools.rs:473

        "Delete every automatically-managed facet from the cache, preserving \
         only user-pinned facets. Irreversible. Only use when the user wants to \
         wipe the assistant's learned model of them."
    }

    fn parameters_schema(&self) -> serde_json::Value {
        json!({ "type": "object", "properties": {} })
    }

    fn permission_level(&self) -> PermissionLevel {
        PermissionLevel::Dangerous
    }

    async fn execute(&self, _args: serde_json::Value) -> anyhow::Result<ToolResult> {
        log::debug!("[tool][learning] reset_cache invoked");
        let cache = get_cache()?;
        let all = cache
            .list_all()
            .map_err(|e| anyhow::anyhow!("learning_reset_cache: {e:#}"))?;
        let pinned_preserved = all
            .iter()
            .filter(|f| f.user_state == UserState::Pinned)
            .count();
        let mut deleted = 0usize;
        for f in &all {
            if f.user_state != UserState::Pinned && cache.delete(&f.key).unwrap_or(false) {
                deleted += 1;
            }
        }
        Ok(ToolResult::success(serde_json::to_string(&json!({
            "deleted": deleted,
            "pinned_preserved": pinned_preserved,
        }))?))
    }
}

/// Write PROFILE.md from supplied markdown. Default-OFF.

View on GitHub (pinned to a221052e0d)

Solutions

  1. Retry the reset when no rebuild/reflection cycle is running
  2. Verify the store is reachable first via learning_cache_stats (cheap read of the same table)
  3. Check the returned 'deleted' count after a successful run — swallowed delete errors under-report, so spot-check with learning_list_facets
Defensive patterns

Strategy: validation

Validate before calling

// Pre-flight: the same table must be readable before a destructive reset
tool_exec("learning_cache_stats", json!({})).await?; // Err => do not reset
tool_exec("learning_list_facets", json!({})).await?;  // note pinned facets to preserve

Try / catch

match tool_exec("learning_reset_cache", json!({})).await {
    Ok(res) => { /* verify: deleted + surviving rows should equal pre-flight list length */ }
    Err(e) => { /* nothing was deleted (failure precedes deletion) — resolve store health, retry */ }
}

Prevention

When it happens

Trigger: Invoking learning_reset_cache while a rebuild or reflection cycle holds/writes the DB; unreadable or corrupted user_profile table; workspace DB missing. Requires the learning_manage tool toggle to even be reachable.

Common situations: User-initiated cache wipe colliding with the nightly stability cycle; reset attempted during core startup before the memory store finished opening.

Related errors


AI-assisted analysis of tinyhumansai/openhuman@a221052e0d (2026-08-16). Data as JSON: /api/errors/77e9c54b584289b6. Report an issue: GitHub.