tinyhumansai/openhuman · error
Failed to canonicalize workspace: {e}
Error message
Failed to canonicalize workspace: {e} What it means
Before any read-modify-write, the tool canonicalizes the workspace root so the target path (workspace + allowed file) can be checked against symlink-based escapes. If std::fs::canonicalize fails — typically the workspace directory was deleted, moved, or is unreadable — this error aborts the operation as a security guard failure, not a content problem.
Source
Thrown at src/openhuman/tools/impl/filesystem/update_memory_md.rs:250
let content = args
.get("content")
.and_then(|v| v.as_str())
.ok_or_else(|| anyhow::anyhow!("Missing 'content' parameter"))?;
// Guard: only allow MEMORY.md and SKILL.md.
if !ALLOWED_FILES.contains(&file) {
return Ok(ToolResult::error(format!(
"File '{file}' is not allowed. Permitted files: MEMORY.md, SKILL.md"
)));
}
let target_path = workspace_dir.join(file);
// Prevent symlink-based workspace escape.
let workspace_canon = self
.workspace_dir_for_context(context)
.canonicalize()
.map_err(|e| anyhow::anyhow!("Failed to canonicalize workspace: {e}"))?;
// Check parent dir exists and canonicalize to detect symlinks.
let parent = target_path.parent().unwrap_or(&workspace_dir);
let parent_canon = parent
.canonicalize()
.unwrap_or_else(|_| parent.to_path_buf());
if !parent_canon.starts_with(&workspace_canon) {
return Ok(ToolResult::error(format!(
"File path '{file}' resolves outside workspace"
)));
}
tracing::debug!("[update_memory_md] action={action} file={file} path={target_path:?}");
// #4458: serialize the whole read-modify-write against concurrent runs
// targeting the same workspace. The guard is held across read + atomic
// write so no interleaving append can be lost.
let lock = workspace_write_lock(&workspace_dir);
let _guard = lock.lock().await;View on GitHub (pinned to 7491200858)
Solutions
- Verify the workspace directory still exists and is readable/writable
- Recreate or re-resolve the workspace root, then retry the tool call
- If the workspace moved, restart the session so tools get the fresh path
Defensive patterns
Strategy: validation
When it happens
Trigger: Thrown at src/openhuman/tools/impl/filesystem/update_memory_md.rs:250 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of tinyhumansai/openhuman@7491200858 (2026-08-17).
Data as JSON: /api/errors/f8157a5ac25a83e3.
Report an issue: GitHub.