{"record":{"id":"282e82a0bbd54dd3","repo":"tinyhumansai/openhuman","slug":"unknown-workflow-definition-definition-id","errorCode":null,"errorMessage":"unknown workflow definition: {definition_id}","messagePattern":"unknown workflow definition: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/openhuman/agent/orchestration/workflow_runs/engine.rs","lineNumber":166,"sourceCode":"/// Start a new workflow run and return immediately.\n///\n/// Resolves `definition_id` to a builtin [`WorkflowDefinition`], creates a\n/// `Running` ledger row with `phase_states` initialised to one `pending` entry\n/// per phase, persists it, then `tokio::spawn`s the engine loop. The returned\n/// [`WorkflowRun`] is the freshly-created row (status `Running`); callers poll\n/// `workflow_run_get` to observe progress.\npub async fn start_workflow_run(\n    config: &Config,\n    definition_id: &str,\n    input: Value,\n    parent_thread_id: Option<String>,\n) -> Result<WorkflowRun> {\n    log::debug!(\n        target: LOG_TARGET,\n        \"[workflow_run_engine] start.entry definition={definition_id} parent_thread={parent_thread_id:?}\"\n    );\n    let definition = definition_by_id(definition_id)\n        .ok_or_else(|| anyhow!(\"unknown workflow definition: {definition_id}\"))?;\n\n    let run_id = format!(\"wfrun-{}\", uuid::Uuid::new_v4());\n    let phase_states = init_phase_states(&definition);\n\n    let run = upsert_workflow_run(\n        &config.workspace_dir,\n        WorkflowRunUpsert {\n            id: run_id.clone(),\n            definition_id: definition.id.clone(),\n            parent_thread_id,\n            input: input.clone(),\n            phase_states,\n            child_run_ids: Vec::new(),\n            status: WorkflowRunStatus::Running,\n            summary: None,\n            started_at: None,\n            completed_at: None,\n        },","sourceCodeStart":148,"sourceCodeEnd":184,"githubUrl":"https://github.com/tinyhumansai/openhuman/blob/a221052e0df5b1f7598fceba7329fd1af95d6699/src/openhuman/agent/orchestration/workflow_runs/engine.rs#L148-L184","documentation":"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.","triggerScenarios":"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.","commonSituations":"Confusing flows (user automations) with workflow-run builtin definitions; version drift after a builtin definition id changed; typos in hardcoded ids.","solutions":["Call the workflow definitions list RPC first and use a returned id verbatim","Confirm you want the workflow-runs engine and not the flows domain for user-authored automations","If the id worked before an upgrade, re-check the builtin list for renames"],"exampleFix":"// before\nstart_workflow_run(&config, \"my-custom-flow\", input, None).await?;\n\n// after — resolve against the live builtin list\nlet def = workflow_runs::ops::definition_by_id(definition_id)\n    .with_context(|| format!(\"unknown workflow definition {definition_id}; known: {:?}\",\n        workflow_runs::ops::list_definitions().definitions.iter().map(|d| d.id.clone()).collect::<Vec<_>>()))?;\nstart_workflow_run(&config, &def.id, input, None).await?;","handlingStrategy":"validation","validationCode":"let def = workflow_runs::ops::definition_by_id(definition_id)\n    .with_context(|| format!(\"unknown workflow definition {definition_id}\"))?;\n// or, over RPC: call the definitions list method and match ids exactly","typeGuard":"fn definition_exists(id: &str) -> bool {\n    workflow_runs::ops::definition_by_id(id).is_some()\n}","tryCatchPattern":"match start_workflow_run(&config, definition_id, input, parent).await {\n    Ok(run) => Ok(run),\n    Err(e) if e.to_string().starts_with(\"unknown workflow definition\") => {\n        let defs = workflow_runs::ops::list_definitions();\n        anyhow::bail!(\"unknown definition {definition_id}; available: {:?}\",\n            defs.definitions.iter().map(|d| d.id.clone()).collect::<Vec<_>>())\n    }\n    Err(e) => Err(e),\n}","preventionTips":["Never hardcode workflow definition ids — fetch the list at runtime and select from it","Do not conflate flows-domain automations with workflow-run builtin definitions","After upgrading the core, refresh the definition list before starting runs"],"tags":["workflow-runs","validation","definitions"],"backgroundTag":null,"analyzedSha":"a221052e0df5b1f7598fceba7329fd1af95d6699","analyzedAt":"2026-08-16T12:47:06.542Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}