{"record":{"id":"fd73659113e1f5c8","repo":"medusajs/medusa","slug":"step-workflow-not-found-data-workflowid-for-st","errorCode":null,"errorMessage":"step workflow not found: ${data.workflowId} for step ${data.id}","messagePattern":"step workflow not found: (.+?) for step (.+?)","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/core/utils/src/dev-server/handlers/step-handler.ts","lineNumber":32,"sourceCode":"\n    if (!data.sourcePath && !data.workflowId) {\n      throw new Error(\n        `Step registration requires either sourcePath or workflowId. Received: ${JSON.stringify(\n          data\n        )}`\n      )\n    }\n  }\n\n  resolveSourcePath(data: StepResourceData): string {\n    if (data.sourcePath) {\n      return data.sourcePath\n    }\n\n    // Look up workflow's source path\n    const workflowKey = `workflow:${data.workflowId}`\n    const workflowSourcePaths = this.inverseRegistry.get(workflowKey)\n\n    if (!workflowSourcePaths || workflowSourcePaths.length === 0) {\n      throw new Error(\n        `step workflow not found: ${data.workflowId} for step ${data.id}`\n      )\n    }\n\n    return workflowSourcePaths[0]\n  }\n\n  createEntry(data: StepResourceData): ResourceEntry {\n    return {\n      id: data.id,\n      workflowId: data.workflowId,\n    }\n  }\n\n  getInverseKey(data: StepResourceData): string {\n    return `${this.type}:${data.id}`","sourceCodeStart":14,"sourceCodeEnd":50,"githubUrl":"https://github.com/medusajs/medusa/blob/5e06e544a296b9033f20f71f11c559f81a0e5739/packages/core/utils/src/dev-server/handlers/step-handler.ts#L14-L50","documentation":"Dev-server error from StepHandler.resolveSourcePath: the step registered with only a workflowId, and the inverse registry has no entry for `workflow:<workflowId>` — meaning that workflow has not been registered with the dev server (or was registered under a different id). Without it the step's source file cannot be located for hot-reload.","triggerScenarios":"Registering a step with workflowId: 'my-workflow' before (or without ever) registering a workflow resource whose id is 'my-workflow'; using the workflow's function name instead of its registered id string.","commonSituations":"Ordering issues in custom loaders where steps load before workflows; renaming a workflow without updating the workflowId referenced by step registrations; registering only part of a project's resources during incremental setup.","solutions":["Register the workflow resource (type 'workflow' with matching id and its sourcePath) before registering its steps.","Verify the workflowId string exactly matches the workflow's registered id.","Alternatively, register the step with its own sourcePath to avoid depending on workflow registration order."],"exampleFix":"// before\nregisterDevServerResource({ type: 'step', id: 's1', workflowId: 'cart-workflow' })\n// 'cart-workflow' never registered\n\n// after\nregisterDevServerResource({ type: 'workflow', id: 'cart-workflow', sourcePath: wfPath })\nregisterDevServerResource({ type: 'step', id: 's1', workflowId: 'cart-workflow' })","handlingStrategy":"validation","validationCode":"if (!data.sourcePath) {\n  const wf = inverseRegistry.get(`workflow:${data.workflowId}`)\n  if (!wf?.length) throw new Error(`Register workflow ${data.workflowId} before its steps`)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Register workflows before their steps in loader ordering.","Use the exact workflow id string from createWorkflow in step registration.","Give steps their own sourcePath to decouple from workflow registration order."],"tags":["dev-server","step","workflow","registry","hot-reload"],"backgroundTag":"unregistered-workflow-reference","analyzedSha":"5e06e544a296b9033f20f71f11c559f81a0e5739","analyzedAt":"2026-08-27T07:24:39.599Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}