tinyhumansai/openhuman · error

unknown workflow run: {id}

Error message

unknown workflow run: {id}

What it means

Thrown by workflow_runs::engine::resume_workflow_run when get_workflow_run finds no persisted run with that id in the workspace run ledger. The lookup is the first step of resume, before status checks, so nothing is mutated when it fires.

Source

Thrown at src/openhuman/agent/orchestration/workflow_runs/engine.rs:293

    )
    .context("persist workflow run interrupt")?;

    log::debug!(target: LOG_TARGET, "[workflow_run_engine] stop.marked_interrupted run={id}");
    Ok(Some(updated))
}

/// Resume an interrupted (or otherwise incomplete) workflow run.
///
/// Reloads the run, clears any stale cancellation flag, flips the row back to
/// `Running`, and spawns a fresh engine loop. Phases already `completed` in
/// `phase_states` are skipped; the loop continues from the first incomplete
/// phase whose dependencies are satisfied. Returns the run row (now `Running`),
/// or an error if the run is unknown / already terminal-complete / its
/// definition no longer exists.
pub async fn resume_workflow_run(config: &Config, id: &str) -> Result<WorkflowRun> {
    log::debug!(target: LOG_TARGET, "[workflow_run_engine] resume.entry run={id}");
    let run = get_workflow_run(&config.workspace_dir, id)?
        .ok_or_else(|| anyhow!("unknown workflow run: {id}"))?;

    if matches!(run.status, WorkflowRunStatus::Completed) {
        return Err(anyhow!("workflow run {id} is already completed"));
    }

    let definition = definition_by_id(&run.definition_id)
        .ok_or_else(|| anyhow!("definition {} no longer exists", run.definition_id))?;

    // Clear any prior cancellation intent and re-register a fresh flag.
    clear_cancel_flag(id);
    register_cancel_flag(id);

    let resumed = upsert_workflow_run(
        &config.workspace_dir,
        WorkflowRunUpsert {
            id: run.id.clone(),
            definition_id: run.definition_id.clone(),
            parent_thread_id: run.parent_thread_id.clone(),

View on GitHub (pinned to a221052e0d)

Solutions

  1. List/get workflow runs in this workspace and confirm the id exists
  2. Verify you are talking to the same core/workspace that started the run
  3. If the run is genuinely gone, start a new run instead of resuming

Example fix

// before
resume_workflow_run(&config, run_id).await?;

// after — guard on existence and fall back to a fresh start
let run = match get_workflow_run(&config.workspace_dir, run_id)? {
    Some(r) => resume_workflow_run(&config, &r.id).await?,
    None => start_workflow_run(&config, definition_id, input, None).await?,
};
Defensive patterns

Strategy: validation

Validate before calling

let run = get_workflow_run(&config.workspace_dir, run_id)?;
anyhow::ensure!(run.is_some(), "unknown workflow run {run_id} — list runs in this workspace first");

Type guard

fn run_exists(config: &Config, run_id: &str) -> bool {
    get_workflow_run(&config.workspace_dir, run_id).map_or(false, |r| r.is_some())
}

Try / catch

match resume_workflow_run(&config, run_id).await {
    Ok(r) => Ok(r),
    Err(e) if e.to_string().starts_with("unknown workflow run") => {
        // run gone (workspace reset?) — restart from a current definition instead
        start_workflow_run(&config, definition_id, input, None).await
    }
    Err(e) => Err(e),
}

Prevention

When it happens

Trigger: Calling workflow run resume with a run id that was never created, was created under a different workspace_dir, or whose ledger row was deleted. Also fires for ids mangled in transit (truncated UUIDs, wrong prefix).

Common situations: Resuming after a workspace reset; the run id copied from another environment/core instance; resuming a run whose create call actually failed.

Related errors


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