{"record":{"id":"23359a77782b625c","repo":"mastra-ai/mastra","slug":"dynamic-workflow-references-tool-entry-toolid","errorCode":null,"errorMessage":"Dynamic workflow references tool \"${entry.toolId}\" which is not registered on this Mastra instance.","messagePattern":"Dynamic workflow references tool \"(.+?)\" which is not registered on this Mastra instance\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/core/src/workflows/dynamic/rehydrate.ts","lineNumber":275,"sourceCode":"    case 'agent': {\n      const agent = tryGetAgentById(mastra, entry.agentId);\n      if (!agent) {\n        throw new Error(\n          `Dynamic workflow references agent \"${entry.agentId}\" which is not registered on this Mastra instance.`,\n        );\n      }\n      return {\n        type: 'agent',\n        id: entry.id,\n        agentId: entry.agentId,\n        agent,\n        options: rebuildAgentOptions(entry, schemaOpts),\n      };\n    }\n    case 'tool': {\n      const tool = mastra.getTool?.(entry.toolId);\n      if (!tool) {\n        throw new Error(\n          `Dynamic workflow references tool \"${entry.toolId}\" which is not registered on this Mastra instance.`,\n        );\n      }\n      return { type: 'tool', id: entry.id, toolId: entry.toolId, tool, options: rebuildToolOptions(entry) };\n    }\n    case 'step': {\n      const { id } = entry.step;\n      // Wrap the resolved agent/tool in a real Step (same adapters `createStep`\n      // uses) so the entry honors the executeStep contract instead of casting a\n      // raw Agent/Tool instance — those don't carry a step-shaped `execute`.\n      const agent = tryGetAgentById(mastra, id);\n      if (agent) {\n        return { type: 'step', step: createStepFromAgent(agent) as unknown as Step };\n      }\n      const tool = tryGetToolById(mastra, id);\n      if (tool) {\n        return { type: 'step', step: createStepFromTool(tool as any) as unknown as Step };\n      }","sourceCodeStart":257,"sourceCodeEnd":293,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/core/src/workflows/dynamic/rehydrate.ts#L257-L293","documentation":"Rehydrating a 'tool' entry requires a tool registered under `entry.toolId` on the target Mastra instance; `mastra.getTool(entry.toolId)` returning undefined causes this throw. Stored dynamic workflows reference tools by id, so any tool id missing from the runtime registry makes reconstruction impossible.","triggerScenarios":"rehydrateWorkflow encounters a stored tool entry whose `toolId` is not resolvable via `mastra.getTool` — the tool was never passed into `new Mastra({ tools: {...} })`, was removed/renamed, or the stored graph came from a different deployment with a different tool set.","commonSituations":"Environment-specific tool registration (tool only exists in dev); renaming tool ids; tool defined in a package not installed in the deploying service; forgetting to include tools in the Mastra constructor.","solutions":["Register the missing tool: `new Mastra({ tools: { '<toolId>': myTool } })` before rehydrating.","Confirm the stored `toolId` matches the registered id exactly after any renames.","Align tool registration across environments (shared registry module) so stored graphs resolve everywhere.","Pre-validate: for each stored tool entry, assert `mastra.getTool(toolId)` is defined before rehydrating."],"exampleFix":"// before\nconst mastra = new Mastra({}); // graph references 'searchTool'\n\n// after\nconst mastra = new Mastra({ tools: { searchTool } });","handlingStrategy":"validation","validationCode":"function assertToolsRegistered(stored, mastra) {\n  for (const e of stored.entries) {\n    if (e.type === 'tool' && !mastra.getTool?.(e.toolId)) {\n      throw new Error(`Tool \"${e.toolId}\" must be registered before rehydration`);\n    }\n  }\n}","typeGuard":"function toolIsRegistered(mastra: Mastra, toolId: string): boolean {\n  return !!mastra.getTool?.(toolId);\n}","tryCatchPattern":"try {\n  const wf = rehydrateWorkflow(stored, mastra);\n} catch (err) {\n  const m = err instanceof Error && err.message.match(/references tool \"([^\"]+)\" which is not registered/);\n  if (m) throw new Error(`Register tool '${m[1]}' on this Mastra instance before rehydrating.`);\n  throw err;\n}","preventionTips":["Register all tools referenced by stored workflows in every deployment environment.","Use a shared tool registry to avoid environment drift.","Track tool id renames and update persisted graphs in the same change."],"tags":["workflow","tool","registration","rehydration"],"backgroundTag":"unregistered-resource-reference","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}