tinyhumansai/openhuman · error
learning_save_profile: summarisation failed: {e:#}
Error message
learning_save_profile: summarisation failed: {e:#} What it means
Thrown by learning_save_profile when summarize=true and linkedin_enrichment::summarise_profile_with_llm() failed. That function sends the raw markdown to the configured LLM provider to produce a condensed profile; failure is an inference-layer problem — no provider/key configured, network failure, rate limit, or the request being rejected (e.g. oversized markdown). The full {e:#} chain names the provider error.
Source
Thrown at src/openhuman/agent/learning/tools.rs:536
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}"))?;
Ok(ToolResult::success(serde_json::to_string(&json!({
"path": path.display().to_string(),
"bytes": body.len(),
}))?))
}
}View on GitHub (pinned to a221052e0d)
Solutions
- Retry with summarize:false — the tool writes the raw markdown to PROFILE.md without the LLM hop
- Verify an inference provider is configured and its key valid (send a trivial chat request)
- Trim the markdown and retry summarize:true
- Check the error chain for 429/401 to distinguish rate limit from auth
Example fix
// before
tool: learning_save_profile {"markdown":"...","summarize":true} // -> summarisation failed: 401 invalid api key
// after: persist raw, summarize later
tool: learning_save_profile {"markdown":"...","summarize":false} // ok, PROFILE.md written Defensive patterns
Strategy: fallback
Validate before calling
// Only request summarisation when a provider is actually configured:
// (settings show an inference provider / API key) — otherwise:
let args = json!({"markdown": md, "summarize": false}); Try / catch
let mut args = json!({"markdown": md, "summarize": true});
match tool_exec("learning_save_profile", args.clone()).await {
Err(e) if e.to_string().contains("summarisation failed") => {
args["summarize"] = json!(false); // degrade: persist raw markdown
tool_exec("learning_save_profile", args).await
}
other => other,
} Prevention
- Configure and verify an inference provider before using summarize:true
- Trim very long profiles before summarising to avoid context/rate limits
- Treat 429s as back-off signals, not permanent failures
When it happens
Trigger: Calling learning_save_profile {markdown, summarize:true} with no inference provider configured or an expired API key; transient network outage; rate-limited provider; an extremely long pasted LinkedIn profile exceeding context/limits.
Common situations: First use of the profile feature before any LLM provider is set up in settings; flaky connectivity; users pasting 50KB profiles.
Related errors
- tick failed: {e}
- learning_enrich_profile: {e:#}
- learning_update_facet: {e:#}
- learning_update_facet: upsert failed: {e:#}
- {tool}: set_user_state failed: {e:#}
AI-assisted analysis of tinyhumansai/openhuman@a221052e0d (2026-08-16).
Data as JSON: /api/errors/7349700c2f2ea458.
Report an issue: GitHub.