medusajs/medusa · error · Error

No handler registered for resource type "${data.type}". Avai

Error message

No handler registered for resource type "${data.type}". Available types: ${Array.from(resourceHandlers.keys()).join(", ")}. Use registerResourceTypeHandler() to add support for custom types.

What it means

Dev-server error from registerDevServerResource: the resource being registered has a `type` for which no handler is registered in the resourceHandlers map. Built-in types (job, step, subscriber, workflow) each have a handler; any other type string is rejected unless you first register a custom handler via registerResourceTypeHandler().

Source

Thrown at packages/core/utils/src/dev-server/index.ts:126

 * })
 * ```
 */
export function registerDevServerResource(data: ResourceRegistrationData): void
export function registerDevServerResource<T extends BaseResourceData>(
  data: T
): void
export function registerDevServerResource<T extends BaseResourceData>(
  data: T
): void {
  // Skip registration in production or if HMR is disabled
  if (!FeatureFlag.isFeatureEnabled("backend_hmr") || isProduction()) {
    return
  }

  const handler = resourceHandlers.get(data.type)

  if (!handler) {
    throw new Error(
      `No handler registered for resource type "${data.type}". ` +
        `Available types: ${Array.from(resourceHandlers.keys()).join(", ")}. ` +
        `Use registerResourceTypeHandler() to add support for custom types.`
    )
  }

  try {
    handler.validate(data)

    const sourcePath = handler.resolveSourcePath(data)

    const registry = getOrCreateRegistry(globalDevServerRegistry, sourcePath)

    const entry = handler.createEntry(data)
    addToRegistry(registry, data.type, entry)

    const inverseKey = handler.getInverseKey(data)
    addToInverseRegistry(inverseDevServerRegistry, inverseKey, sourcePath)

View on GitHub (pinned to 5e06e544a2)

Solutions

  1. Use one of the built-in types listed in the error message: job, step, subscriber, workflow.
  2. Fix typos in the type string so it exactly matches a registered type.
  3. For a genuinely custom type, implement a ResourceTypeHandler and call registerResourceTypeHandler(type, handler) before any registerDevServerResource call for it.
  4. If the type should be built-in, upgrade/downgrade so the framework utils version matches the code performing registration.

Example fix

// before
registerDevServerResource({ type: 'my-widget', ... }) // no handler

// after
registerResourceTypeHandler('my-widget', myWidgetHandler)
registerDevServerResource({ type: 'my-widget', ... })
Defensive patterns

Strategy: validation

Validate before calling

const BUILT_IN = ['job', 'step', 'subscriber', 'workflow']
if (!BUILT_IN.includes(data.type)) {
  throw new Error(`Register a handler for custom type "${data.type}" via registerResourceTypeHandler() first`)
}

Type guard

function isKnownResourceType(type: unknown, handlers: Map<string, unknown>): type is string {
  return typeof type === 'string' && handlers.has(type)
}

Prevention

When it happens

Trigger: Calling registerDevServerResource({ type: 'api-key' | 'widget' | 'route' | ... }) for a type with no handler; typos in the type string like 'workflows' or 'subscribber'; registering a custom resource kind before implementing its handler.

Common situations: Extending Medusa's dev server with new resource kinds (custom loaders, plugins with their own resource types); version drift where a type exists in newer framework code but the running dev server build lacks its handler; copy-paste registrations with a wrong type literal.

Related errors


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