medusajs/medusa · error · MedusaError
Order is not a draft
Error message
Order is not a draft
What it means
Shared utility behind validateDraftOrderChangeStep: any order-change operation on a draft order requires the order to be a draft (status DRAFT or is_draft_order flag); otherwise it throws INVALID_DATA.
Source
Thrown at packages/core/core-flows/src/draft-order/utils/validation.ts:14
import {
MedusaError,
OrderStatus,
PromotionStatus,
} from "@medusajs/framework/utils"
import type { OrderDTO, PromotionDTO } from "@medusajs/framework/types"
interface ThrowIfNotDraftOrderInput {
order: OrderDTO
}
export function throwIfNotDraftOrder({ order }: ThrowIfNotDraftOrderInput) {
if (order.status !== OrderStatus.DRAFT && !order.is_draft_order) {
throw new MedusaError(
MedusaError.Types.INVALID_DATA,
"Order is not a draft"
)
}
}
function getMessageByCount(count: number, singular: string, plural: string) {
return count === 1 ? singular : plural
}
export function throwIfCodesAreMissing(
promo_codes: string[],
promotions: PromotionDTO[]
) {
const missingPromoCodes = promo_codes.filter(
(code) => !promotions.some((promotion) => promotion.code === code)
)
View on GitHub (pinned to 5e06e544a2)
Solutions
- Verify draft state (status/is_draft_order) before invoking the change workflow
- Use order-edit workflows for non-draft orders
- Refetch order state at operation time instead of trusting cached client state
Example fix
// before
await addDraftOrderItemsWorkflow(container).run({ input: { order_id: orderId, items: [...] } }) // non-draft order
// after
if (order.status === "draft" || order.is_draft_order) {
await addDraftOrderItemsWorkflow(container).run({ input: { order_id: orderId, items: [...] } })
} else {
await beginOrderEditOrderWorkflow(container).run({ input: { order_id: orderId } })
} Defensive patterns
Strategy: type-guard
Validate before calling
import { OrderStatus } from "@medusajs/framework/utils"
if (order.status !== OrderStatus.DRAFT && !order.is_draft_order) {
// route to order-edit flows instead
} Type guard
const isDraftOrder = (o: { status: string; is_draft_order?: boolean }) => o.status === "draft" || !!o.is_draft_order Prevention
- Refetch order state at operation time
- Disable draft-order UI actions once the order is confirmed
When it happens
Trigger: Any draft-order change workflow (add/update/remove items or promo codes) invoked on an order whose status is not draft and is_draft_order is falsy.
Common situations: Draft already confirmed; mixing up regular order edits with draft-order workflows; concurrent confirmation between read and write.
Related errors
- Order ${order.id} is not a draft order
- --paths must be a directory - ${additionalPath}
- --base must be a file - ${baseFile}
- insufficient_inventory
- not_found
AI-assisted analysis of medusajs/medusa@5e06e544a2 (2026-08-27).
Data as JSON: /api/errors/b60fd24b8718d829.
Report an issue: GitHub.