medusajs/medusa · error · MedusaError

invalid_data

invalid_data

Error message

The promotion code ${code} is invalid

What it means

Identical to the getRunningTransaction case but hit via retryStep in the Redis engine: the idempotency key is parsed into workflowId/transactionId, and if the workflow isn't in the MedusaWorkflow registry, retry is aborted with this error.

Source

Thrown at packages/core/core-flows/src/cart/steps/get-promotion-codes-to-apply.ts:120

              await query.graph(
                {
                  entity: "promotion",
                  fields: ["id", "code"],
                  filters: { code: promo_codes },
                },
                {
                  cache: {
                    enable: true,
                  },
                }
              )
            ).data.map((p) => p.code!)
          : []
      )

      promo_codes.forEach((code) => {
        if (!validPromoCodes.has(code)) {
          throw new MedusaError(
            MedusaError.Types.INVALID_DATA,
            `The promotion code ${code} is invalid`
          )
        }
        promotionCodesToApply.add(code)
      })
    }

    return new StepResponse(
      Array.from(promotionCodesToApply) as GetPromotionCodesToApplyStepOutput
    )
  }
)

View on GitHub (pinned to 5e06e544a2)

Solutions

  1. Retry using the idempotency key originally returned by the engine
  2. Import the workflow module in the retrying process
  3. Validate the key's workflowId against the registry before calling

Example fix

// before
await engine.retryStep(key)
// after
if (!MedusaWorkflow.getWorkflow(parseKey(key).workflowId)) throw new Error('unknown workflow')
await engine.retryStep(key)
Defensive patterns

Strategy: type-guard

Validate before calling

const [_, { workflowId }] = engine.buildIdempotencyKeyAndParts(idempotencyKey)
if (!MedusaWorkflow.getWorkflow(workflowId)) throw new Error('unknown workflow in key')
await engine.retryStep(idempotencyKey)

Type guard

const isRetryableKey = (k: string) => Boolean(MedusaWorkflow.getWorkflow(engine.buildIdempotencyKeyAndParts(k)[1].workflowId))

Try / catch

catch (e) { if (e.message.includes('not found')) return deadLetter(key); throw e }

Prevention

When it happens

Trigger: engine.retryStep(idempotencyKey) with a malformed key or a key whose workflowId references a workflow not loaded in this process.

Common situations: Retry handlers in separate workers that don't import the original workflow; hand-built keys; key-format drift across versions.

Related errors


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