medusajs/medusa · error · MedusaError
Product options are not provided for: [${missingOptionsProdu
Error message
Product options are not provided for: [${missingOptionsProductTitles.join(", ")}]. What it means
Thrown by the create-products workflow when one or more products in the input have no options array (or an empty one). Options are required because variants are defined against option value combinations; a product without options cannot have well-formed variants. This is an INVALID_DATA validation error raised before any product is created.
Source
Thrown at packages/core/core-flows/src/product/workflows/create-products.ts:83
* ],
* manage_inventory: true,
* },
* ]
* }
* ]
* })
*/
export const validateProductInputStep = createStep(
validateProductInputStepId,
async (data: ValidateProductInputStepInput) => {
const { products } = data
const missingOptionsProductTitles = products
.filter((product) => !product.options?.length)
.map((product) => product.title)
if (missingOptionsProductTitles.length) {
throw new MedusaError(
MedusaError.Types.INVALID_DATA,
`Product options are not provided for: [${missingOptionsProductTitles.join(
", "
)}].`
)
}
}
)
/**
* The data to create one or more products, along with custom data that's passed to the workflow's hooks.
*/
export type CreateProductsWorkflowInput = {
/**
* The products to create.
*/
products: CreateProductWorkflowInputDTO[]
} & AdditionalDataView on GitHub (pinned to 5e06e544a2)
Solutions
- Add an options array to every product in the payload, e.g. options: [{ title: 'Default Option', values: ['Default'] }]
- If migrating older code, replicate the previous behavior by supplying a default option explicitly
- Validate payloads before submission (see validation snippet) so the whole batch isn't rejected for one product
Example fix
// before
const products = [{ title: 'Shirt', variants: [...] }]
await createProductsWorkflow(container).run({ input: { products } })
// after
const products = [{
title: 'Shirt',
options: [{ title: 'Size', values: ['S', 'M'] }],
variants: [{ title: 'S', options: { Size: 'S' } }],
}]
await createProductsWorkflow(container).run({ input: { products } }) Defensive patterns
Strategy: validation
Validate before calling
const missing = products.filter((p) => !p.options?.length).map((p) => p.title)
if (missing.length) throw new Error(`Products missing options: ${missing.join(', ')}`)
await createProductsWorkflow(container).run({ input: { products } }) Type guard
const allProductsHaveOptions = (products: { options?: unknown[] }[]): boolean => products.every((p) => Array.isArray(p.options) && p.options.length > 0) Try / catch
try { await createProductsWorkflow(scope).run({ input }) } catch (e) { if (e instanceof MedusaError && /options are not provided/.test(e.message)) { /* add default options and retry */ } else throw e } Prevention
- Treat options as required in your product DTO types (make the field non-optional)
- Default to options: [{ title: 'Default', values: ['Default'] }] when no real options exist
- Validate the batch client-side so one bad product doesn't reject the rest
When it happens
Trigger: Calling createProductsWorkflow or POST /admin/products with a product payload lacking options: [] (or passing options as undefined), especially when manage_inventory_variant or variant creation is expected later.
Common situations: Building product payloads programmatically and conditionally including options only when present; assuming options are optional because the type marks them optional; migrating from an older version where options were auto-generated (a default 'Title' option).
Understand the failure class
Background: "Missing required field" and "field is required" errors: why libraries reject payloads that omit mandatory fields — this error's family across 20 libraries.
Related errors
- Cannot associate duplicate inventory items to variant(s) ${e
- --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/2807c4186f65d502.
Report an issue: GitHub.