medusajs/medusa · error · Error

Action not found.

Error message

Action not found.

What it means

After resolving a transaction from a responseIdempotencyKey, the orchestrator looks up the step named by the key's action segment in the transaction's flow. If getStepByAction returns null, the action does not exist in that flow — a malformed key or a flow-definition change removed the step.

Source

Thrown at packages/core/orchestration/src/transaction/transaction-orchestrator.ts:1858

        )
      }

      transaction = new DistributedTransaction(
        existingTransaction.flow,
        handler!,
        undefined,
        existingTransaction.errors,
        existingTransaction.context
      )
    }

    const step = TransactionOrchestrator.getStepByAction(
      transaction.getFlow(),
      action
    )

    if (step === null) {
      throw new Error("Action not found.")
    } else if (
      step.isCompensating()
        ? actionType !== TransactionHandlerType.COMPENSATE
        : actionType !== TransactionHandlerType.INVOKE
    ) {
      throw new Error("Incorrect action type.")
    }
    return [transaction, step]
  }

  /** Skip the execution of a specific transaction and step
   * @param responseIdempotencyKey - The idempotency key for the step
   * @param handler - The handler function to execute the step
   * @param transaction - The current transaction. If not provided it will be loaded based on the responseIdempotencyKey
   */
  public async skipStep({
    responseIdempotencyKey,
    handler,

View on GitHub (pinned to 5e06e544a2)

Solutions

  1. Verify the action segment of the key matches a current step alias in the workflow definition
  2. Discard/ack stale callbacks whose keys reference removed steps
  3. Never hand-build idempotency keys; use the key returned by the engine

Example fix

// before
const key = `${modelId}:${txId}:oldStepName:invoke`
await orchestrator.transactionStepResponse(key)

// after
// use the key provided by the engine (e.g. from step.context.idempotencyKey)
await orchestrator.transactionStepResponse(engineProvidedKey)
Defensive patterns

Strategy: try-catch

Validate before calling

// Validate key structure before use
const [modelId, txId, action, type] = key.split(':')
if (!modelId || !txId || !action || !['invoke', 'compensate'].includes(type)) {
  throw new Error(`Malformed idempotency key: ${key}`)
}

Try / catch

try { await orchestrator.transactionStepResponse(key, null, handler) } catch (e) { if (/Action not found/.test(e.message)) return /* stale key */ throw e }

Prevention

When it happens

Trigger: Processing a step response whose idempotency key contains an action alias that is not present in the loaded transaction's flow — e.g. keys generated by an older workflow version, hand-built keys, or keys decoded incorrectly (separator mismatch).

Common situations: Deploying a workflow change that renamed/removed a step while old async callbacks with old keys still arrive; constructing responseIdempotencyKey manually with a wrong action segment.

Related errors


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