{"record":{"id":"ed2aeccdd2168873","repo":"tinyhumansai/openhuman","slug":"learning-save-profile-write-failed-e","errorCode":null,"errorMessage":"learning_save_profile: write failed: {e}","messagePattern":"learning_save_profile: write failed: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/openhuman/agent/learning/tools.rs","lineNumber":548,"sourceCode":"            .map_err(|e| anyhow::anyhow!(\"learning_save_profile: {e}\"))?;\n        let body = if summarize {\n            crate::openhuman::agent::learning::linkedin_enrichment::summarise_profile_with_llm(\n                &config, &markdown,\n            )\n            .await\n            .map_err(|e| anyhow::anyhow!(\"learning_save_profile: summarisation failed: {e:#}\"))?\n        } else {\n            markdown\n        };\n        let path = config.workspace_dir.join(\"PROFILE.md\");\n        if let Some(parent) = path.parent() {\n            tokio::fs::create_dir_all(parent)\n                .await\n                .map_err(|e| anyhow::anyhow!(\"learning_save_profile: create dir failed: {e}\"))?;\n        }\n        tokio::fs::write(&path, &body)\n            .await\n            .map_err(|e| anyhow::anyhow!(\"learning_save_profile: write failed: {e}\"))?;\n        Ok(ToolResult::success(serde_json::to_string(&json!({\n            \"path\": path.display().to_string(),\n            \"bytes\": body.len(),\n        }))?))\n    }\n}\n\n/// Enrich the profile via LinkedIn (external scrape). Default-OFF.\npub struct LearningEnrichProfileTool;\n\n#[async_trait]\nimpl Tool for LearningEnrichProfileTool {\n    fn name(&self) -> &str {\n        \"learning_enrich_profile\"\n    }\n\n    fn description(&self) -> &str {\n        \"Run the LinkedIn profile-enrichment pipeline: optionally with a preset \\","sourceCodeStart":530,"sourceCodeEnd":566,"githubUrl":"https://github.com/tinyhumansai/openhuman/blob/a221052e0df5b1f7598fceba7329fd1af95d6699/src/openhuman/agent/learning/tools.rs#L530-L566","documentation":"Thrown by learning_save_profile when the final tokio::fs::write() of PROFILE.md into workspace_dir fails. The directory was ensured successfully one step earlier, so this is a file-level failure: permission on the file itself, disk full, or the file being held exclusively by another process. Nothing is persisted — the body (possibly an LLM summary you paid for) is lost unless retried.","triggerScenarios":"An existing read-only PROFILE.md (checked into a repo, chmod 444); disk filling between the create_dir_all and the write; antivirus/sync clients (Windows OneDrive, AV) holding the file; a text editor with an exclusive lock open.","commonSituations":"Users keep their workspace in a synced/read-only folder; CI running the core against a constrained sandbox; PROFILE.md owned by root after a sudo run.","solutions":["Check permissions on the existing PROFILE.md (chmod/chown or delete it so the tool recreates it)","Free disk space and retry — note a summarize:true retry re-invokes the LLM; prefer summarize:false if the summary was already produced","Exclude the workspace from AV/sync locks or close editors holding the file","Retry the tool once the blocker is removed"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"let path = cfg.workspace_dir.join(\"PROFILE.md\");\nif path.exists() {\n    let md = std::fs::metadata(&path)?;\n    assert!(md.permissions().readonly() == false, \"PROFILE.md is read-only — fix before save\");\n}","typeGuard":null,"tryCatchPattern":"match tool_exec(\"learning_save_profile\", args).await {\n    Err(e) if e.to_string().contains(\"write failed\") => {\n        // check: ENOSPC -> free space; EACCES -> chmod/chown PROFILE.md; success dir exists, so it's file-level\n        Err(e)\n    }\n    other => other,\n}","preventionTips":["Don't make PROFILE.md read-only or lock it in an editor/sync client while the agent writes it","Watch disk space — the dir create succeeds on a full disk but the write fails","A failed write loses the (possibly LLM-summarised) body — keep the source markdown until success is confirmed"],"tags":["rust","filesystem","io","learning","profile"],"backgroundTag":null,"analyzedSha":"a221052e0df5b1f7598fceba7329fd1af95d6699","analyzedAt":"2026-08-16T12:47:06.542Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}