tinyhumansai/openhuman · error · anyhow::Error
artifact_list: {e}
Error message
artifact_list: {e} What it means
Wrapper around `ops::ai_list_artifacts(&config, offset, limit, None)` failing in ArtifactListTool::execute. The chain goes store::list_artifacts → artifacts_root (create_dir_all on `<workspace>/artifacts/`), so failures are workspace-IO-shaped: the workspace dir cannot be created/read (permissions, path is a file, disk error). Note the tool intentionally passes thread_id=None to list the whole workspace (#3226) — filtering bugs are not the failure mode here.
Source
Thrown at src/openhuman/agent/artifacts/tools.rs:91
"type": "object",
"properties": {
"offset": { "type": "integer", "minimum": 0, "description": "Pagination offset (default 0)." },
"limit": { "type": "integer", "minimum": 1, "description": "Max artifacts to return (default 50, cap 200)." }
}
})
}
async fn execute(&self, args: serde_json::Value) -> anyhow::Result<ToolResult> {
log::debug!("[tool][artifacts] list invoked");
let offset = read_opt_usize(&args, "offset");
let limit = read_opt_usize(&args, "limit");
// The agent-facing tool surface lists everything in the workspace;
// the per-chat filter is an RPC-only knob used by the React panel
// (#3226). Keep the tool path unchanged so existing agent flows
// (orchestrator artifact reasoning) still see the full set.
let outcome = ops::ai_list_artifacts(&self.config, offset, limit, None)
.await
.map_err(|e| anyhow::anyhow!("artifact_list: {e}"))?;
Ok(ToolResult::success(serde_json::to_string(&outcome.value)?))
}
fn is_concurrency_safe(&self, _args: &serde_json::Value) -> bool {
true
}
}
/// Retrieve a single artifact's metadata plus its absolute on-disk path.
pub struct ArtifactGetTool {
config: Arc<Config>,
}
impl ArtifactGetTool {
pub fn new(config: Arc<Config>) -> Self {
Self { config }
}
}View on GitHub (pinned to a221052e0d)
Solutions
- Check the inner `{e}` — it names the exact IO operation and path.
- Confirm `config.workspace_dir` exists, is a directory, and is readable+writable by the core process.
- Create the artifacts root manually (`mkdir -p <workspace>/artifacts`) to surface any permission error early.
- If workspace_dir came from a flag/env, point it back at the real workspace.
- Re-mount/repair the underlying filesystem if removable/network storage is involved.
Example fix
# before: workspace_dir=/mnt/usb/openhuman (drive unmounted -> mkdir fails) # after ls -ld /mnt/usb/openhuman && mkdir -p /mnt/usb/openhuman/artifacts openhuman ... # or set workspace_dir back to ~/.openhuman/users/<id>
Defensive patterns
Strategy: try-catch
Validate before calling
// Verify the workspace is usable before invoking the tool:
let root = config.workspace_dir.join("artifacts");
std::fs::create_dir_all(&root)?; // surfaces permission/path errors here, with a clear context Try / catch
match ArtifactListTool::new(config.clone()).execute(args).await {
Ok(res) => res,
Err(e) if e.to_string().starts_with("artifact_list:") => {
// Inner error is IO-shaped; check workspace_dir mount/permissions,
// log and degrade gracefully (empty list) rather than failing the turn.
ToolResult::success(serde_json::to_string(&serde_json::json!({"artifacts": [], "total": 0}))?)
}
Err(e) => return Err(e),
} Prevention
- Keep workspace_dir on reliable local storage.
- Pre-create <workspace>/artifacts at deploy time to fail fast on permission problems.
- Treat list failures as empty-state candidates in agent flows after logging.
When it happens
Trigger: The agent invokes artifact_list while config.workspace_dir points at an unwritable/removable path, a path whose parent is a file, or a filesystem with an I/O error. An empty or missing artifacts dir normally yields a clean empty listing, not this error.
Common situations: Workspace on an unmounted external drive/network share; workspace_dir overridden via -w/--workspace or env to a bad path; sandboxed agent runtime denying FS access to the workspace; artifacts dir corrupted mid-scan.
Related errors
- artifact_get: {e}
- missing required string argument `{key}`
- artifact_delete: {e}
- learning_save_profile: write failed: {e}
- learning_update_facet: {e:#}
AI-assisted analysis of tinyhumansai/openhuman@a221052e0d (2026-08-16).
Data as JSON: /api/errors/d48960bc31d73e69.
Report an issue: GitHub.