{"record":{"id":"2807c4186f65d502","repo":"medusajs/medusa","slug":"product-options-are-not-provided-for-missingop","errorCode":null,"errorMessage":"Product options are not provided for: [${missingOptionsProductTitles.join(\", \")}].","messagePattern":"Product options are not provided for: \\[(.+?)\\]\\.","errorType":"validation","errorClass":"MedusaError","httpStatus":400,"severity":"error","filePath":"packages/core/core-flows/src/product/workflows/create-products.ts","lineNumber":83,"sourceCode":" *           ],\n *           manage_inventory: true,\n *         },\n *       ]\n *     }\n *   ]\n * })\n */\nexport const validateProductInputStep = createStep(\n  validateProductInputStepId,\n  async (data: ValidateProductInputStepInput) => {\n    const { products } = data\n\n    const missingOptionsProductTitles = products\n      .filter((product) => !product.options?.length)\n      .map((product) => product.title)\n\n    if (missingOptionsProductTitles.length) {\n      throw new MedusaError(\n        MedusaError.Types.INVALID_DATA,\n        `Product options are not provided for: [${missingOptionsProductTitles.join(\n          \", \"\n        )}].`\n      )\n    }\n  }\n)\n\n/**\n * The data to create one or more products, along with custom data that's passed to the workflow's hooks.\n */\nexport type CreateProductsWorkflowInput = {\n  /**\n   * The products to create.\n   */\n  products: CreateProductWorkflowInputDTO[]\n} & AdditionalData","sourceCodeStart":65,"sourceCodeEnd":101,"githubUrl":"https://github.com/medusajs/medusa/blob/5e06e544a296b9033f20f71f11c559f81a0e5739/packages/core/core-flows/src/product/workflows/create-products.ts#L65-L101","documentation":"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.","triggerScenarios":"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.","commonSituations":"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).","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"],"exampleFix":"// before\nconst products = [{ title: 'Shirt', variants: [...] }]\nawait createProductsWorkflow(container).run({ input: { products } })\n\n// after\nconst products = [{\n  title: 'Shirt',\n  options: [{ title: 'Size', values: ['S', 'M'] }],\n  variants: [{ title: 'S', options: { Size: 'S' } }],\n}]\nawait createProductsWorkflow(container).run({ input: { products } })","handlingStrategy":"validation","validationCode":"const missing = products.filter((p) => !p.options?.length).map((p) => p.title)\nif (missing.length) throw new Error(`Products missing options: ${missing.join(', ')}`)\nawait createProductsWorkflow(container).run({ input: { products } })","typeGuard":"const allProductsHaveOptions = (products: { options?: unknown[] }[]): boolean => products.every((p) => Array.isArray(p.options) && p.options.length > 0)","tryCatchPattern":"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 }","preventionTips":["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"],"tags":["products","options","validation","core-flows"],"backgroundTag":"missing-required-field","analyzedSha":"5e06e544a296b9033f20f71f11c559f81a0e5739","analyzedAt":"2026-08-27T07:24:39.599Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}