{"record":{"id":"efbef185f8860137","repo":"tinyhumansai/openhuman","slug":"definition-no-longer-exists","errorCode":null,"errorMessage":"definition {} no longer exists","messagePattern":"definition (.+?) no longer exists","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/openhuman/agent/orchestration/workflow_runs/engine.rs","lineNumber":300,"sourceCode":"/// Resume an interrupted (or otherwise incomplete) workflow run.\n///\n/// Reloads the run, clears any stale cancellation flag, flips the row back to\n/// `Running`, and spawns a fresh engine loop. Phases already `completed` in\n/// `phase_states` are skipped; the loop continues from the first incomplete\n/// phase whose dependencies are satisfied. Returns the run row (now `Running`),\n/// or an error if the run is unknown / already terminal-complete / its\n/// definition no longer exists.\npub async fn resume_workflow_run(config: &Config, id: &str) -> Result<WorkflowRun> {\n    log::debug!(target: LOG_TARGET, \"[workflow_run_engine] resume.entry run={id}\");\n    let run = get_workflow_run(&config.workspace_dir, id)?\n        .ok_or_else(|| anyhow!(\"unknown workflow run: {id}\"))?;\n\n    if matches!(run.status, WorkflowRunStatus::Completed) {\n        return Err(anyhow!(\"workflow run {id} is already completed\"));\n    }\n\n    let definition = definition_by_id(&run.definition_id)\n        .ok_or_else(|| anyhow!(\"definition {} no longer exists\", run.definition_id))?;\n\n    // Clear any prior cancellation intent and re-register a fresh flag.\n    clear_cancel_flag(id);\n    register_cancel_flag(id);\n\n    let resumed = upsert_workflow_run(\n        &config.workspace_dir,\n        WorkflowRunUpsert {\n            id: run.id.clone(),\n            definition_id: run.definition_id.clone(),\n            parent_thread_id: run.parent_thread_id.clone(),\n            input: run.input.clone(),\n            phase_states: run.phase_states.clone(),\n            child_run_ids: run.child_run_ids.clone(),\n            status: WorkflowRunStatus::Running,\n            summary: run.summary.clone(),\n            started_at: Some(run.started_at),\n            completed_at: None,","sourceCodeStart":282,"sourceCodeEnd":318,"githubUrl":"https://github.com/tinyhumansai/openhuman/blob/a221052e0df5b1f7598fceba7329fd1af95d6699/src/openhuman/agent/orchestration/workflow_runs/engine.rs#L282-L318","documentation":"Thrown by workflow_runs::engine::resume_workflow_run when the run row exists but definition_by_id(run.definition_id) no longer resolves — the builtin workflow definition the run was started under is not offered by the current binary. Definitions are compiled-in builtins, so this is version drift between the run's creation and the resume attempt.","triggerScenarios":"Starting a run on one core version, upgrading (or switching to a build where the builtin was renamed/removed), then resuming the persisted run. Also reproducible by manually editing a run row's definition_id.","commonSituations":"App auto-update between an interrupted run and a later resume; resuming old runs after a dev iteration that changed builtin definitions; mixed-version fleet where runs migrate between builds.","solutions":["Start a fresh run with a definition id from the current list_definitions instead of resuming","Clean up / archive runs whose definition_id no longer resolves so they stop appearing resumable","Keep builtin definition ids stable across releases if old runs must remain resumable"],"exampleFix":"// before\nresume_workflow_run(&config, &run_id).await?; // fails: definition gone after upgrade\n\n// after — verify the definition still exists, else restart from scratch\nlet run = get_workflow_run(&config.workspace_dir, &run_id)?.context(\"unknown run\")?;\nlet resumed = match workflow_runs::ops::definition_by_id(&run.definition_id) {\n    Some(_) => resume_workflow_run(&config, &run_id).await?,\n    None => start_workflow_run(&config, &current_definition_id, run.input.clone(), run.parent_thread_id).await?,\n};","handlingStrategy":"validation","validationCode":"let run = get_workflow_run(&config.workspace_dir, run_id)?.context(\"unknown run\")?;\nif workflow_runs::ops::definition_by_id(&run.definition_id).is_none() {\n    // definition gone in this build — restart with a current definition instead of resuming\n}","typeGuard":"fn definition_still_available(definition_id: &str) -> bool {\n    workflow_runs::ops::definition_by_id(definition_id).is_some()\n}","tryCatchPattern":"match resume_workflow_run(&config, run_id).await {\n    Ok(r) => Ok(r),\n    Err(e) if e.to_string().contains(\"no longer exists\") => {\n        start_workflow_run(&config, &current_definition_id, run.input.clone(), run.parent_thread_id).await\n    }\n    Err(e) => Err(e),\n}","preventionTips":["Before resuming across an upgrade, check the run's definition_id against the current list_definitions","Keep builtin workflow definition ids immutable across releases so old runs stay resumable","Archive unresolvable runs so resumable lists only contain runs the current build can execute"],"tags":["workflow-runs","version-drift","definitions","upgrade"],"backgroundTag":null,"analyzedSha":"a221052e0df5b1f7598fceba7329fd1af95d6699","analyzedAt":"2026-08-16T12:47:06.542Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}