{"record":{"id":"85dc36fe19bad642","repo":"mastra-ai/mastra","slug":"cannot-time-travel-to-step-targetstepid-the","errorCode":null,"errorMessage":"Cannot time travel to step '${targetStepId}': the step does not exist in the current execution graph. The workflow definition has likely changed since the run was recorded (renamed step, or an unnamed .map() step whose generated id changed across processes). Steps recorded in the snapshot: ${reportedIdsSuffix}. The stored snapshot has not been modified.","messagePattern":"Cannot time travel to step '(.+?)': the step does not exist in the current execution graph\\. The workflow definition has likely changed since the run was recorded \\(renamed step, or an unnamed \\.map\\(\\) step whose generated id changed across processes\\)\\. Steps recorded in the snapshot: (.+?)\\. The stored snapshot has not been modified\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/core/src/workflows/utils.ts","lineNumber":374,"sourceCode":"}): void => {\n  const { targetStepId, graph, snapshot, context } = params;\n  const snapshotContext = (snapshot.context ?? {}) as Record<string, any>;\n  const recordedStepIds = Object.keys(snapshotContext).filter(key => key !== 'input');\n\n  // Empty snapshot context: nothing recorded, nothing to protect.\n  if (recordedStepIds.length === 0) {\n    return;\n  }\n\n  const targetEntryIndex = graph.steps.findIndex(entry => getStepIds(entry).includes(targetStepId));\n  const reportedIds = recordedStepIds.slice(0, MAX_REPORTED_SNAPSHOT_IDS);\n  const reportedIdsSuffix =\n    recordedStepIds.length > MAX_REPORTED_SNAPSHOT_IDS\n      ? `${reportedIds.join(', ')} (and ${recordedStepIds.length - MAX_REPORTED_SNAPSHOT_IDS} more)`\n      : reportedIds.join(', ');\n\n  if (targetEntryIndex === -1) {\n    throw new Error(\n      `Cannot time travel to step '${targetStepId}': the step does not exist in the current execution graph. ` +\n        `The workflow definition has likely changed since the run was recorded (renamed step, or an unnamed .map() ` +\n        `step whose generated id changed across processes). Steps recorded in the snapshot: ${reportedIdsSuffix}. ` +\n        `The stored snapshot has not been modified.`,\n    );\n  }\n\n  const hasRecordedEntry = (stepId: string) => snapshotContext[stepId] != null || context?.[stepId] != null;\n\n  const missingStepIds: string[] = [];\n  for (const [index, entry] of graph.steps.entries()) {\n    if (index >= targetEntryIndex) {\n      break;\n    }\n    // sleep / sleepUntil entries and zero-iteration foreach / loop entries may\n    // legitimately have no recorded snapshot entry.\n    if (entry.type === 'sleep' || entry.type === 'sleepUntil' || entry.type === 'foreach' || entry.type === 'loop') {\n      continue;","sourceCodeStart":356,"sourceCodeEnd":392,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/core/src/workflows/utils.ts#L356-L392","documentation":"assertTimeTravelGraphMatchesSnapshot throws when the target step id for a time-travel operation does not exist in the current execution graph snapshot. It fires when targetEntryIndex === -1, meaning the workflow definition changed since the run was recorded (renamed step, or an unnamed .map() whose generated id differs across processes). The stored snapshot is left unmodified.","triggerScenarios":"Calling createTimeTravelExecutionParams (which calls assertTimeTravelGraphMatchesSnapshot) with a targetStepId not present in the recorded snapshot's step ids — after renaming a step in code, deploying a changed workflow against old persisted runs, or time-traveling to an unnamed .map() step whose generated id differs between processes.","commonSituations":"Deploying updated workflow definitions while old runs are replayed; referencing steps by auto-generated ids; renaming/refactoring steps without migrating stored snapshots.","solutions":["Use a target step id that matches one of the ids listed in the error message ('Steps recorded in the snapshot: ...').","Give map() steps an explicit, stable id so generated ids do not change across processes.","Align the workflow definition with the version that recorded the run, or re-record the run.","If many ids are shown with '(and N more)', inspect the full snapshot to find valid ids."],"exampleFix":"// before\n.map({ id: undefined, execute: ... }) // generated id changes per process\ntimeTravel(runId, ['generated-unknown-step']);\n// after\n.map({ id: 'transform-items', execute: ... })\ntimeTravel(runId, ['transform-items']);","handlingStrategy":"validation","validationCode":"function assertStepInSnapshot(stepId: string, snapshotIds: string[]) {\n  if (!snapshotIds.includes(stepId)) throw new Error(`'${stepId}' not in snapshot; known: ${snapshotIds.join(', ')}`);\n}","typeGuard":null,"tryCatchPattern":"try {\n  await workflow.timeTravel(runId, [targetStepId]);\n} catch (e) {\n  if ((e as Error).message.includes('does not exist in the current execution graph')) {\n    const ids = (e as Error).message.match(/snapshot: (.+)\\./)?.[1] ?? '';\n    console.error(`Pick a valid step id from snapshot: ${ids}`);\n  } else throw e;\n}","preventionTips":["Give all steps — especially .map() steps — explicit stable ids","Keep workflow definitions and stored runs version-aligned when deploying","Avoid targeting auto-generated step ids across processes","Re-record or re-run workflows after refactoring step names"],"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"}