medusajs/medusa · error · Error
If a transaction is not provided, the handler is required
Error message
If a transaction is not provided, the handler is required
What it means
TransactionOrchestrator's step-response APIs (e.g. transactionStepResponse / resumeByResponseIdempotencyKey) can resolve a transaction either from a passed DistributedTransaction or by loading it via a handler using the responseIdempotencyKey. If neither is provided, it has no way to locate the transaction and throws this plain Error.
Source
Thrown at packages/core/orchestration/src/transaction/transaction-orchestrator.ts:1824
): TransactionStep | null {
for (const key in flow.steps) {
if (action === flow.steps[key]?.definition?.action) {
return flow.steps[key]
}
}
return null
}
private static async getTransactionAndStepFromIdempotencyKey(
responseIdempotencyKey: string,
handler?: TransactionStepHandler,
transaction?: DistributedTransactionType
): Promise<[DistributedTransactionType, TransactionStep]> {
const [modelId, transactionId, action, actionType] =
responseIdempotencyKey.split(TransactionOrchestrator.SEPARATOR)
if (!transaction && !handler) {
throw new Error(
"If a transaction is not provided, the handler is required"
)
}
if (!transaction) {
const existingTransaction =
await TransactionOrchestrator.loadTransactionById(
modelId,
transactionId
)
if (existingTransaction === null) {
throw new MedusaError(
MedusaError.Types.NOT_FOUND,
`Transaction ${transactionId} could not be found.`
)
}
View on GitHub (pinned to 5e06e544a2)
Solutions
- Pass the handler argument (loader) so the orchestrator can fetch the transaction by model/transaction id
- Or pass the DistributedTransaction instance you already hold
Example fix
// before await orchestrator.resumeByResponseIdempotencyKey(key) // after await orchestrator.resumeByResponseIdempotencyKey( key, async (modelId, txId) => loadTxFromStorage(modelId, txId) )
Defensive patterns
Strategy: validation
Validate before calling
if (!transaction && !handler) {
throw new Error('Provide a DistributedTransaction or a loader handler')
}
await orchestrator.transactionStepResponse(key, transaction, handler) Prevention
- Always pass the storage-loader handler when only an idempotency key is available (async callback scenarios)
When it happens
Trigger: Calling a method like resumeByResponseIdempotencyKey/getTransactionStepByAction with a responseIdempotencyKey but passing neither a transaction object nor a handler (the function used to load the transaction from storage).
Common situations: Custom integrations responding to async step callbacks (e.g. webhook completing a waitFor step) where the developer only passes the idempotency key, forgetting the handler that loads persisted state.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- Method 'clearTransactionTimeout' not implemented.
- Method 'scheduleStepTimeout' not implemented.
- Method 'clearStepTimeout' not implemented.
- Method 'clearExpiredExecutions' not implemented.
- Unable to serialize context object. Please make sure the wor
AI-assisted analysis of medusajs/medusa@5e06e544a2 (2026-08-27).
Data as JSON: /api/errors/0cba12e89a4a3bee.
Report an issue: GitHub.