tinyhumansai/openhuman · error

unknown workflow definition: {definition_id}

Error message

unknown workflow definition: {definition_id}

What it means

Thrown by workflow_runs::engine::start_workflow_run when definition_by_id cannot resolve the definition_id. Definitions come exclusively from builtin_definitions() (currently the single parallel-research workflow), so any id outside that builtin set fails before a run row is created.

Source

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

/// Start a new workflow run and return immediately.
///
/// Resolves `definition_id` to a builtin [`WorkflowDefinition`], creates a
/// `Running` ledger row with `phase_states` initialised to one `pending` entry
/// per phase, persists it, then `tokio::spawn`s the engine loop. The returned
/// [`WorkflowRun`] is the freshly-created row (status `Running`); callers poll
/// `workflow_run_get` to observe progress.
pub async fn start_workflow_run(
    config: &Config,
    definition_id: &str,
    input: Value,
    parent_thread_id: Option<String>,
) -> Result<WorkflowRun> {
    log::debug!(
        target: LOG_TARGET,
        "[workflow_run_engine] start.entry definition={definition_id} parent_thread={parent_thread_id:?}"
    );
    let definition = definition_by_id(definition_id)
        .ok_or_else(|| anyhow!("unknown workflow definition: {definition_id}"))?;

    let run_id = format!("wfrun-{}", uuid::Uuid::new_v4());
    let phase_states = init_phase_states(&definition);

    let run = upsert_workflow_run(
        &config.workspace_dir,
        WorkflowRunUpsert {
            id: run_id.clone(),
            definition_id: definition.id.clone(),
            parent_thread_id,
            input: input.clone(),
            phase_states,
            child_run_ids: Vec::new(),
            status: WorkflowRunStatus::Running,
            summary: None,
            started_at: None,
            completed_at: None,
        },

View on GitHub (pinned to a221052e0d)

Solutions

  1. Call the workflow definitions list RPC first and use a returned id verbatim
  2. Confirm you want the workflow-runs engine and not the flows domain for user-authored automations
  3. If the id worked before an upgrade, re-check the builtin list for renames

Example fix

// before
start_workflow_run(&config, "my-custom-flow", input, None).await?;

// after — resolve against the live builtin list
let def = workflow_runs::ops::definition_by_id(definition_id)
    .with_context(|| format!("unknown workflow definition {definition_id}; known: {:?}",
        workflow_runs::ops::list_definitions().definitions.iter().map(|d| d.id.clone()).collect::<Vec<_>>()))?;
start_workflow_run(&config, &def.id, input, None).await?;
Defensive patterns

Strategy: validation

Validate before calling

let def = workflow_runs::ops::definition_by_id(definition_id)
    .with_context(|| format!("unknown workflow definition {definition_id}"))?;
// or, over RPC: call the definitions list method and match ids exactly

Type guard

fn definition_exists(id: &str) -> bool {
    workflow_runs::ops::definition_by_id(id).is_some()
}

Try / catch

match start_workflow_run(&config, definition_id, input, parent).await {
    Ok(run) => Ok(run),
    Err(e) if e.to_string().starts_with("unknown workflow definition") => {
        let defs = workflow_runs::ops::list_definitions();
        anyhow::bail!("unknown definition {definition_id}; available: {:?}",
            defs.definitions.iter().map(|d| d.id.clone()).collect::<Vec<_>>())
    }
    Err(e) => Err(e),
}

Prevention

When it happens

Trigger: Calling workflow run start with a made-up, renamed, or user-flow id — e.g. assuming a saved flow from the flows domain can be started as a workflow run, or hardcoding an id from an older/newer version whose builtin set differs.

Common situations: Confusing flows (user automations) with workflow-run builtin definitions; version drift after a builtin definition id changed; typos in hardcoded ids.

Related errors


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