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

  1. Check the inner `{e}` — it names the exact IO operation and path.
  2. Confirm `config.workspace_dir` exists, is a directory, and is readable+writable by the core process.
  3. Create the artifacts root manually (`mkdir -p <workspace>/artifacts`) to surface any permission error early.
  4. If workspace_dir came from a flag/env, point it back at the real workspace.
  5. 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

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


AI-assisted analysis of tinyhumansai/openhuman@a221052e0d (2026-08-16). Data as JSON: /api/errors/d48960bc31d73e69. Report an issue: GitHub.