{"record":{"id":"729f69398580b21e","repo":"ruvnet/ruflo","slug":"workflow-cannot-be-resumed","errorCode":null,"errorMessage":"Workflow cannot be resumed","messagePattern":"Workflow cannot be resumed","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"v3/@claude-flow/shared/src/plugins/official/maestro-plugin.ts","lineNumber":251,"sourceCode":"  /**\n   * Pause a workflow\n   */\n  pauseWorkflow(workflowId: string): boolean {\n    const workflow = this.workflows.get(workflowId);\n    if (!workflow || workflow.status !== 'running') return false;\n\n    this.checkpointWorkflow(workflow);\n    workflow.status = 'paused';\n    return true;\n  }\n\n  /**\n   * Resume a paused workflow\n   */\n  async resumeWorkflow(workflowId: string): Promise<OrchestrationResult> {\n    const workflow = this.workflows.get(workflowId);\n    if (!workflow || workflow.status !== 'paused') {\n      throw new Error('Workflow cannot be resumed');\n    }\n\n    // Restore from checkpoint and continue\n    return this.executeWorkflow(workflowId);\n  }\n\n  /**\n   * Get workflow status\n   */\n  getWorkflow(workflowId: string): Workflow | undefined {\n    return this.workflows.get(workflowId);\n  }\n\n  /**\n   * List all workflows\n   */\n  listWorkflows(): Workflow[] {\n    return Array.from(this.workflows.values());","sourceCodeStart":233,"sourceCodeEnd":269,"githubUrl":"https://github.com/ruvnet/ruflo/blob/fa13ee4ad60ac2090b1480656eb233521790d640/v3/@claude-flow/shared/src/plugins/official/maestro-plugin.ts#L233-L269","documentation":"Thrown by MaestroPlugin.resumeWorkflow() when the given workflowId is not present in the plugin's in-memory workflow registry, or when the workflow's status is anything other than 'paused'. Only workflows explicitly parked via pauseWorkflow() (which checkpoints state and sets status='paused') are resumable; resume simply re-enters executeWorkflow(). It is a lifecycle state-machine guard, not a crash: running, completed, failed, or unknown workflows all refuse to resume.","triggerScenarios":"Calling maestro.resumeWorkflow(id) while the workflow is still 'running' (pauseWorkflow never called or not yet awaited); resuming a 'completed' or 'failed' workflow; passing a workflowId that was never created with this plugin instance; calling resume after a process restart, since the workflows map is in-memory and the id no longer resolves.","commonSituations":"A resume button or API endpoint wired straight to resumeWorkflow without a status check; user clicks resume after the run already finished; plugin instance recreated on deploy/restart losing in-memory state; race where resume fires before pause completes.","solutions":["Call and await pauseWorkflow(workflowId) first — only status 'paused' can be resumed.","Guard the call: const wf = maestro.getWorkflow(workflowId); proceed only when wf && wf.status === 'paused'.","If getWorkflow(id) is undefined, the id is wrong or in-memory state was lost — re-create the workflow instead of resuming.","For terminal statuses ('completed', 'failed'), start a new workflow run rather than resuming the old one."],"exampleFix":"// before\nawait maestro.resumeWorkflow(workflowId); // throws unless status === 'paused'\n\n// after\nconst wf = maestro.getWorkflow(workflowId);\nif (!wf) throw new Error(`unknown workflow ${workflowId}`);\nif (wf.status !== 'paused') {\n  await maestro.pauseWorkflow(workflowId);\n}\nconst result = await maestro.resumeWorkflow(workflowId);","handlingStrategy":"validation","validationCode":"const wf = maestro.getWorkflow(workflowId);\nconst resumable = !!wf && wf.status === 'paused';\nif (!resumable) {\n  // pause the workflow first, or start a new run — do not call resumeWorkflow\n}","typeGuard":"function isResumableWorkflow(wf: Workflow | undefined): wf is Workflow & { status: 'paused' } {\n  return wf !== undefined && wf.status === 'paused';\n}","tryCatchPattern":"try {\n  await maestro.resumeWorkflow(workflowId);\n} catch (e) {\n  if (e instanceof Error && e.message === 'Workflow cannot be resumed') {\n    const wf = maestro.getWorkflow(workflowId);\n    if (!wf) { /* unknown id: re-create the workflow */ }\n    else if (wf.status === 'completed' || wf.status === 'failed') { /* start a new run */ }\n    else { /* still running: wait, then pause + resume */ }\n  } else {\n    throw e;\n  }\n}","preventionTips":["Drive resume affordances (buttons, API routes) from getWorkflow(id)?.status — only show them while 'paused'.","Always pair pauseWorkflow and resumeWorkflow, and await pause before enabling resume.","Workflow state is in-memory per plugin instance — persist ids and statuses externally to survive restarts."],"tags":["workflow","state-machine","orchestration","maestro-plugin"],"backgroundTag":"invalid-state-transition","analyzedSha":"fa13ee4ad60ac2090b1480656eb233521790d640","analyzedAt":"2026-08-18T21:34:22.708Z","schemaVersion":2},"datasetVersion":"2026-08-22T04:17:13.399Z"}