medusajs/medusa · error · Error

Step registration requires id. Received: ${JSON.stringify(da

Error message

Step registration requires id. Received: ${JSON.stringify(data)}

What it means

Dev-server validation error from StepHandler.validate: a workflow-step resource was registered without an `id`. Steps are tracked in an inverse registry (which workflow uses which step file) to support hot-reload, so a missing id aborts registration.

Source

Thrown at packages/core/utils/src/dev-server/handlers/step-handler.ts:8

import { ResourceEntry, ResourceTypeHandler, StepResourceData } from "../types"

export class StepHandler implements ResourceTypeHandler<StepResourceData> {
  readonly type = "step"

  constructor(private inverseRegistry: Map<string, string[]>) {}

  validate(data: StepResourceData): void {
    if (!data.id) {
      throw new Error(
        `Step registration requires id. Received: ${JSON.stringify(data)}`
      )
    }

    if (!data.sourcePath && !data.workflowId) {
      throw new Error(
        `Step registration requires either sourcePath or workflowId. Received: ${JSON.stringify(
          data
        )}`
      )
    }
  }

  resolveSourcePath(data: StepResourceData): string {
    if (data.sourcePath) {
      return data.sourcePath

View on GitHub (pinned to 5e06e544a2)

Solutions

  1. Pass the step's unique id (the first argument given to createStep) in the registration data.
  2. If the id is computed, assert it is a non-empty string before registering.
  3. Register steps with type 'step' and include either sourcePath or workflowId alongside the id.

Example fix

// before
registerDevServerResource({ type: 'step', sourcePath, workflowId }) // no id

// after
registerDevServerResource({ type: 'step', id: 'create-order-step', sourcePath, workflowId })
Defensive patterns

Strategy: validation

Validate before calling

if (!data.id) throw new Error(`Missing step id: ${JSON.stringify(data)}`)

Type guard

function isStepResourceData(d: unknown): d is StepResourceData {
  return !!d && typeof (d as any).id === 'string' && !!(d as any).sourcePath || !!(d as any).workflowId
}

Prevention

When it happens

Trigger: Calling the step registration API with data lacking the step id — typically the step's unique name string; loaders that derive ids from step configuration and end up with undefined; registering an inline arrow-function step that was never assigned a name.

Common situations: Custom tooling or plugins that auto-register steps from files; refactoring step names while the registration path still reads the old property; creating steps with createStep dynamically where the id variable is misspelled.

Related errors


AI-assisted analysis of medusajs/medusa@5e06e544a2 (2026-08-27). Data as JSON: /api/errors/4c7d71b803ed7328. Report an issue: GitHub.