tinyhumansai/openhuman · error

[agent] replay list_active_runs failed: {e}

Error message

[agent] replay list_active_runs failed: {e}

What it means

Active-run listing failed: one of list_by_thread / list_by_root / list_active on FileStatusStore errored (replay/ops.rs:154). The thread/root/active query selection happens before the store call, so the failure is in reading the kv status store itself — lock contention, missing or corrupt workspace store, permissions.

Source

Thrown at src/openhuman/agent/tinyagents/replay/ops.rs:154

pub(crate) async fn list_active_runs(
    workspace: &Path,
    thread_id: Option<&str>,
    root_run_id: Option<&str>,
) -> anyhow::Result<Vec<HarnessRunStatus>> {
    log::debug!(
        "[agent] replay list_active_runs thread_id={:?} root_run_id={:?}",
        thread_id,
        root_run_id
    );
    let stores = open_session_stores(workspace);
    let store = FileStatusStore::new(stores.kv);

    let base = match (thread_id, root_run_id) {
        (Some(thread), _) => store.list_by_thread(thread).await,
        (None, Some(root)) => store.list_by_root(root).await,
        (None, None) => store.list_active().await,
    }
    .map_err(|e| anyhow::anyhow!("[agent] replay list_active_runs failed: {e}"))?;

    let mut runs: Vec<HarnessRunStatus> = base.into_iter().filter(is_active).collect();
    // If a caller supplied BOTH a thread and a root, the thread query drove the
    // base list; narrow it to the requested root as well.
    if thread_id.is_some() {
        if let Some(root) = root_run_id {
            runs.retain(|s| s.root_run_id.as_str() == root);
        }
    }

    log::debug!("[agent] replay list_active_runs returned={}", runs.len());
    Ok(runs)
}

#[cfg(test)]
mod tests {
    use super::*;
    use std::sync::Arc;

View on GitHub (pinned to a221052e0d)

Solutions

  1. Verify the workspace path is accessible and writable
  2. Retry the listing after the concurrent writer finishes — busy locks are transient
  3. If the status store is corrupted (crash mid-write), rebuild the workspace session stores
  4. Run listing queries from the process that owns the workspace
Defensive patterns

Strategy: retry

Validate before calling

if std::fs::metadata(workspace).is_err() {
    anyhow::bail!("workspace missing at {} — cannot list runs", workspace.display());
}

Try / catch

// Listing is poll-shaped: degrade gracefully instead of failing the caller
match list_active_runs(workspace, thread_id, root_run_id).await {
    Ok(runs) => runs,
    Err(e) if is_transient_store_error(&e) => Vec::new(), // retry next poll tick
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Listing active runs while another process holds the kv store lock; workspace directory moved or restored; corrupted status store; permission changes on the workspace tree.

Common situations: Dashboards/UI polling active runs against a busy core; resumed/recovered workspaces after a crash; shared workspaces across processes.

Related errors


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