tinyhumansai/openhuman · error
learning_save_profile: {e}
Error message
learning_save_profile: {e} What it means
Thrown by learning_save_profile when config_rpc::load_config_with_timeout() fails before the markdown can be written. That helper loads the TOML Config (with env overrides) under a bounded deadline inside the process; failure means the config file was unreadable/invalid or the load exceeded its timeout (Display-only {e}, no error chain). Without a Config the tool cannot resolve workspace_dir for PROFILE.md.
Source
Thrown at src/openhuman/agent/learning/tools.rs:530
},
"required": ["markdown"]
})
}
fn permission_level(&self) -> PermissionLevel {
PermissionLevel::Write
}
async fn execute(&self, args: serde_json::Value) -> anyhow::Result<ToolResult> {
log::debug!("[tool][learning] save_profile invoked");
let markdown = read_required_str(&args, "markdown")?;
let summarize = args
.get("summarize")
.and_then(serde_json::Value::as_bool)
.unwrap_or(false);
let config = config_rpc::load_config_with_timeout()
.await
.map_err(|e| anyhow::anyhow!("learning_save_profile: {e}"))?;
let body = if summarize {
crate::openhuman::agent::learning::linkedin_enrichment::summarise_profile_with_llm(
&config, &markdown,
)
.await
.map_err(|e| anyhow::anyhow!("learning_save_profile: summarisation failed: {e:#}"))?
} else {
markdown
};
let path = config.workspace_dir.join("PROFILE.md");
if let Some(parent) = path.parent() {
tokio::fs::create_dir_all(parent)
.await
.map_err(|e| anyhow::anyhow!("learning_save_profile: create dir failed: {e}"))?;
}
tokio::fs::write(&path, &body)
.await
.map_err(|e| anyhow::anyhow!("learning_save_profile: write failed: {e}"))?;View on GitHub (pinned to a221052e0d)
Solutions
- Validate config.toml parses (openhuman config RPC get, or re-run the core) and fix reported syntax/type errors
- Retry once filesystem contention clears — the timeout variant fails transiently under lock pressure
- Confirm the workspace directory exists and the user has write access
- Check OPENHUMAN_* env overrides for a misrouted workspace path
Defensive patterns
Strategy: retry
Validate before calling
// Verify config loads before invoking the tool: // via RPC: config.get (any read) — if the config is broken this fails the same way // in-process: config_rpc::load_config_with_timeout().await.is_ok()
Try / catch
match tool_exec("learning_save_profile", args).await {
Err(e) if e.to_string().starts_with("learning_save_profile:") && !e.to_string().contains("failed") => {
// config-load failure: fix config.toml first, then retry — no partial writes happened
Err(e)
}
other => other,
} Prevention
- Validate config.toml after every manual edit (the core logs parse errors at startup)
- Keep the workspace on local disk — network home dirs blow the load timeout
- A failed config load aborts before any file write, so a plain retry after fixing config is safe
When it happens
Trigger: Hand-edited config.toml with syntax errors or invalid typed fields; config load blocked behind a contended lock until the timeout fired; workspace/config directory missing or unreadable; env override pointing at a bad path.
Common situations: User edits config.toml and leaves a typo, then asks the agent to save their profile; slow/locked filesystem (network home dir) blowing the load timeout; fresh machine without an initialized workspace.
Related errors
- learning_enrich_profile: {e}
- timed out waiting for core at ${coreUrl} ${stderrFn()}
- API base URL must be an absolute http(s) URL with host
- agent registry rejected after merging workspace overrides fr
- learning_update_facet: {e:#}
AI-assisted analysis of tinyhumansai/openhuman@a221052e0d (2026-08-16).
Data as JSON: /api/errors/6585fbc6f7f7e841.
Report an issue: GitHub.