{"record":{"id":"53ef55fe8d6dcfd4","repo":"medusajs/medusa","slug":"items-should-be-present-as-an-array-in-the-conte","errorCode":null,"errorMessage":"\"items\" should be present as an array in the context to compute actions","messagePattern":"\"items\" should be present as an array in the context to compute actions","errorType":"validation","errorClass":"MedusaError","httpStatus":400,"severity":"error","filePath":"packages/modules/promotion/src/utils/compute-actions/buy-get.ts","lineNumber":33,"sourceCode":"import { areRulesValidForContext } from \"../validations\"\nimport { computeActionForBudgetExceeded } from \"./usage\"\nimport { Promotion } from \"@models\"\n\nexport type EligibleItem = {\n  item_id: string\n  quantity: BigNumberInput\n}\n\nfunction sortByPrice(a: ComputeActionItemLine, b: ComputeActionItemLine) {\n  return MathBN.lt(a.subtotal, b.subtotal) ? 1 : -1\n}\n\nfunction isValidPromotionContext(\n  promotion: PromotionTypes.PromotionDTO | InferEntityType<typeof Promotion>,\n  itemsContext: ComputeActionItemLine[]\n): boolean {\n  if (!itemsContext) {\n    throw new MedusaError(\n      MedusaError.Types.INVALID_DATA,\n      `\"items\" should be present as an array in the context to compute actions`\n    )\n  }\n\n  if (!itemsContext?.length) {\n    return false\n  }\n\n  const minimumBuyQuantity = MathBN.convert(\n    promotion.application_method?.buy_rules_min_quantity ?? 0\n  )\n\n  if (\n    MathBN.lte(minimumBuyQuantity, 0) ||\n    !promotion.application_method?.buy_rules?.length\n  ) {\n    return false","sourceCodeStart":15,"sourceCodeEnd":51,"githubUrl":"https://github.com/medusajs/medusa/blob/5e06e544a296b9033f20f71f11c559f81a0e5739/packages/modules/promotion/src/utils/compute-actions/buy-get.ts#L15-L51","documentation":"computeActions for a buy-get promotion requires the computation context to contain an 'items' array (ComputeActionItemLine[]). isValidPromotionContext throws INVALID_DATA when itemsContext is null/undefined, because buy-get rules (buy X get Y) cannot be evaluated without line items.","triggerScenarios":"Calling promotionModule.computeActions([promoCode], {}) or with a context missing the items key while any applicable promotion is of type buyget; also passing items: null explicitly.","commonSituations":"Running computeActions for cart-level discounts without loading the cart first, reusing a shipping-only context (shipping_methods only) with a buy-get code, integration tests with empty context fixtures.","solutions":["Populate context.items with the cart's line items mapped to ComputeActionItemLine (id, quantity, unit_price, etc.) before calling computeActions","If computing only shipping adjustments, ensure the buy-get promotion code is not passed in the promotionCodes array","Load the cart via CartModule and transform its items into the expected shape"],"exampleFix":"// before\nawait promotionModule.computeActions([\"BUYGET_CODE\"], {\n  shipping_methods: [...],\n})\n\n// after\nawait promotionModule.computeActions([\"BUYGET_CODE\"], {\n  items: cart.items.map((i) => ({\n    id: i.id,\n    quantity: i.quantity,\n    unit_price: i.unit_price,\n    variant_id: i.variant_id,\n    product_id: i.product_id,\n  })),\n  shipping_methods: [...],\n})","handlingStrategy":"validation","validationCode":"const context = { ...rawContext, items: rawContext.items ?? [] }\nif (!Array.isArray(context.items)) context.items = []","typeGuard":"const hasItemsContext = (ctx: Record<string, unknown>): boolean => Array.isArray(ctx.items)","tryCatchPattern":"try { await computeActions(codes, context) } catch (e) { if (e.type === MedusaError.Types.INVALID_DATA && /items.*context/.test(e.message)) { /* hydrate items from cart and retry */ } throw e }","preventionTips":["Always build the full context (items + shipping_methods) from the cart","Default missing keys to empty arrays, not undefined","Skip buy-get codes when computing shipping-only adjustments"],"tags":["promotion","compute-actions","buy-get","context","medusa"],"backgroundTag":"missing-required-context","analyzedSha":"5e06e544a296b9033f20f71f11c559f81a0e5739","analyzedAt":"2026-08-27T07:24:39.599Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}