{"record":{"id":"9eede9751bcbe4ef","repo":"mastra-ai/mastra","slug":"cannot-time-travel-to-step-targetstepid-step","errorCode":null,"errorMessage":"Cannot time travel to step '${targetStepId}': step(s) ${missingStepIds.map(id => `'${id}'`).join(', ')} precede the target in the current execution graph but were not recorded in the snapshot. Either the workflow definition changed since the run was recorded (renamed steps, or unnamed .map() steps whose generated ids changed across processes), or the recorded run never reached these steps (it failed, was canceled, or was suspended before them). Steps recorded in the snapshot: ${reportedIdsSuffix}. The stored snapshot has not been modified.","messagePattern":"Cannot time travel to step '\\$\\{targetStepId\\}': step\\(s\\) \\$\\{missingStepIds\\.map\\(id => `'\\$\\{id\\}'`\\)\\.join\\(', '\\)\\} precede the target in the current execution graph but were not recorded in the snapshot\\. Either the workflow definition changed since the run was recorded \\(renamed steps, or unnamed \\.map\\(\\) steps whose generated ids changed across processes\\), or the recorded run never reached these steps \\(it failed, was canceled, or was suspended before them\\)\\. Steps recorded in the snapshot: \\$\\{reportedIdsSuffix\\}\\. The stored snapshot has not been modified\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/core/src/workflows/utils.ts","lineNumber":411,"sourceCode":"    }\n    const stepIds = getStepIds(entry);\n    if (entry.type === 'conditional') {\n      // A pre-target conditional is healthy when at least one of its branch steps\n      // was recorded; unselected branches legitimately have no entry.\n      if (stepIds.length > 0 && !stepIds.some(hasRecordedEntry)) {\n        missingStepIds.push(...stepIds);\n      }\n      continue;\n    }\n    for (const stepId of stepIds) {\n      if (!hasRecordedEntry(stepId)) {\n        missingStepIds.push(stepId);\n      }\n    }\n  }\n\n  if (missingStepIds.length > 0) {\n    throw new Error(\n      `Cannot time travel to step '${targetStepId}': step(s) ${missingStepIds.map(id => `'${id}'`).join(', ')} ` +\n        `precede the target in the current execution graph but were not recorded in the snapshot. Either the ` +\n        `workflow definition changed since the run was recorded (renamed steps, or unnamed .map() steps whose ` +\n        `generated ids changed across processes), or the recorded run never reached these steps (it failed, was ` +\n        `canceled, or was suspended before them). Steps recorded in the snapshot: ${reportedIdsSuffix}. ` +\n        `The stored snapshot has not been modified.`,\n    );\n  }\n};\n\nexport const createTimeTravelExecutionParams = (params: {\n  steps: string[];\n  inputData?: any;\n  resumeData?: any;\n  context?: TimeTravelContext<any, any, any, any>;\n  nestedStepsContext?: Record<string, TimeTravelContext<any, any, any, any>>;\n  snapshot: WorkflowRunState;\n  initialState?: any;","sourceCodeStart":393,"sourceCodeEnd":429,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/core/src/workflows/utils.ts#L393-L429","documentation":"assertTimeTravelGraphMatchesSnapshot throws when steps that precede the time-travel target in the current execution graph are missing from the recorded snapshot. This means either the workflow definition changed (renamed steps / changed generated .map() ids) or the recorded run genuinely never reached those steps (failed, canceled, or suspended before them). The stored snapshot is not modified.","triggerScenarios":"Calling createTimeTravelExecutionParams with a target whose upstream (preceding) step ids in the current graph are absent from the snapshot — e.g. replaying an old run that failed early against a re-ordered or renamed workflow, or graph re-ordering introduced a new predecessor step after the run was recorded.","commonSituations":"Modifying workflow step order/dependencies between the recorded run and the time-travel request; runs terminated before completing all prior steps; deployment skew between writer and replayer processes.","solutions":["Check the listed missing step ids: if the definition changed, revert/rename to match or re-record the run.","If the run legitimately never reached those steps, time-travel to a target at or before the point the run reached, or re-run the workflow.","Give steps stable explicit ids so graph comparisons remain valid across processes.","Validate the workflow version against the run's recorded version before time travel."],"exampleFix":"// before\n// run recorded before adding 'enrich' step; target 'score' now has predecessor 'enrich'\ntimeTravel(runId, ['score']);\n// after\ntimeTravel(runId, ['enrich']); // or re-run the workflow with the new definition","handlingStrategy":"validation","validationCode":"function assertPredecessorsRecorded(targetId: string, graphPredecessors: string[], snapshotIds: string[]) {\n  const missing = graphPredecessors.filter(id => !snapshotIds.includes(id));\n  if (missing.length) throw new Error(`Predecessor steps missing from snapshot: ${missing.join(', ')}`);\n}","typeGuard":null,"tryCatchPattern":"try {\n  await workflow.timeTravel(runId, [targetStepId]);\n} catch (e) {\n  if ((e as Error).message.includes('precede the target')) {\n    console.error('Run did not reach predecessors or definition changed; pick an earlier target or re-run.');\n  } else throw e;\n}","preventionTips":["Ensure runs complete (or suspend cleanly) before enabling time travel to downstream steps","Keep step order and ids stable across deployments","Time-travel to the furthest step the run actually reached","Verify workflow version matches the recorded run's version"],"tags":["workflows","time-travel","snapshot-mismatch","execution-graph"],"backgroundTag":"time-travel-step-not-found","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}