medusajs/medusa · error · MedusaError

Invalid step input

Error message

Invalid step input

What it means

Defensive branch in maybeUnsetDefaultShippingAddressesStep: the input matched neither the 'remove' nor the 'update' shape, so the step cannot determine which addresses to unflag. Unreachable for well-formed workflow input.

Source

Thrown at packages/core/core-flows/src/customer/steps/maybe-unset-default-shipping-addresses.ts:91

    if (isDefined(data.create)) {
      // eslint-disable-next-line @medusajs/step-must-return-step-response
      return unsetForCreate(
        data.create,
        customerModuleService,
        "is_default_shipping"
      )
    }

    if (isDefined(data.update)) {
      // eslint-disable-next-line @medusajs/step-must-return-step-response
      return unsetForUpdate(
        data.update,
        customerModuleService,
        "is_default_shipping"
      )
    }

    throw new MedusaError(
      MedusaError.Types.INVALID_DATA, 
      "Invalid step input"
    )
  },
  async (addressesToSet, { container }) => {
    if (!addressesToSet?.length) {
      return
    }

    const customerModuleService = container.resolve<ICustomerModuleService>(
      Modules.CUSTOMER
    )

    await customerModuleService.updateCustomerAddresses(
      { id: addressesToSet },
      { is_default_shipping: true }
    )
  }

View on GitHub (pinned to 5e06e544a2)

Solutions

  1. Ensure the step input contains either data.remove or data.update (updates touching is_default_shipping)
  2. Use official customer workflows instead of the raw step
  3. Pin/upgrade @medusajs/core-flows to match the step's expected input type

Example fix

// before
await maybeUnsetDefaultShippingAddressesStep(container).run({
  input: { data: {} },
})

// after
await maybeUnsetDefaultShippingAddressesStep(container).run({
  input: { data: { update: [{ id: addrId, is_default_shipping: true, customer_id }] } },
})
Defensive patterns

Strategy: type-guard

Validate before calling

if (!data.remove && !data.update) throw new Error('Step input must include remove or update')

Type guard

const hasRemoveOrUpdate = (d: { remove?: unknown; update?: unknown }) => !!(d?.remove || d?.update)

Prevention

When it happens

Trigger: Invoking maybeUnsetDefaultShippingAddressesStep directly with an input lacking both data.remove and data.update.

Common situations: Custom workflow composing the internal step with hand-built payload; renamed input keys after upgrade; type drift between versions.

Related errors


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