medusajs/medusa · error · MedusaError

Inventory availability cannot be calculated in the given con

Error message

Inventory availability cannot be calculated in the given context. Either provide a single sales channel id or configure a single sales channel in the publishable key

What it means

Thrown by wrapVariantsWithInventoryQuantityForSalesChannel when calculating variant inventory availability requires exactly one sales channel but the context yields zero or several: neither the publishable key nor the request narrows it to a single channel. Inventory quantities are per-location/stock-location tied to sales channels, so 'in stock' is undefined across multiple channels at once.

Source

Thrown at packages/medusa/src/api/utils/middlewares/products/variant-inventory-quantity.ts:75

}

export const wrapVariantsWithInventoryQuantityForSalesChannel = async (
  req: MedusaStoreRequest<unknown>,
  variants: VariantInput[]
) => {
  const salesChannelIds = transformAndValidateSalesChannelIds(req)

  const publishableApiKeySalesChannelIds =
    req.publishable_key_context.sales_channel_ids ?? []

  let channelsToUse: string

  if (publishableApiKeySalesChannelIds.length === 1) {
    channelsToUse = publishableApiKeySalesChannelIds[0]
  } else if (salesChannelIds.length === 1) {
    channelsToUse = salesChannelIds[0]
  } else {
    throw new MedusaError(
      MedusaError.Types.INVALID_DATA,
      `Inventory availability cannot be calculated in the given context. Either provide a single sales channel id or configure a single sales channel in the publishable key`
    )
  }

  const variantsToWrap = (variants ?? []).filter(
    (variant): variant is VariantInput => !!variant?.id
  )
  const variantIds = variantsToWrap.map((variant) => variant.id)

  if (!variantIds.length) {
    return
  }

  const query = req.scope.resolve(ContainerRegistrationKeys.QUERY)
  const availability = await getVariantAvailability(query, {
    variant_ids: variantIds,
    sales_channel_id: channelsToUse,

View on GitHub (pinned to 5e06e544a2)

Solutions

  1. Add a single sales_channel_id query param to the request
  2. Restrict the publishable key to exactly one sales channel if the storefront only serves one
  3. If multiple channels are intentional, fetch inventory per channel with separate requests

Example fix

// before
GET /store/products/variants (key has sc_web + sc_app, no filter)

// after
GET /store/products/variants?sales_channel_id=sc_web
Defensive patterns

Strategy: validation

Validate before calling

// resolve exactly one channel before requesting inventory availability
const { sales_channels } = await fetch('/store/sales-channels', {
  headers: { 'x-publishable-api-key': PK },
}).then(r => r.json())
const channelId = requestedScId ?? (sales_channels.length === 1 ? sales_channels[0].id : null)
if (!channelId) throw new Error('pin a single sales channel')
// then pass sales_channel_id: channelId on the request

Type guard

const hasSingleChannel = (
  filterIds: string[] | undefined,
  keyChannelIds: string[]
): boolean => keyChannelIds.length === 1 || (filterIds?.length ?? 0) === 1

Try / catch

try {
  await listVariantsWithInventory()
} catch (e) {
  if (e.type === 'invalid_data' && /Inventory availability/.test(e.message)) {
    // retry with an explicit single sales_channel_id
  }
  throw e
}

Prevention

When it happens

Trigger: Requesting variants with inventory (e.g. listing product variants through this middleware) when the publishable key has 2+ sales channels AND the request's sales_channel_id filter is absent or contains 2+ ids (or both resolve to none).

Common situations: Publishable key linked to multiple sales channels (e.g. web + app) and the storefront doesn't pin a channel; passing an array of sales_channel_id values expecting aggregated availability.

Related errors


AI-assisted analysis of medusajs/medusa@5e06e544a2 (2026-08-27). Data as JSON: /api/errors/1af45a6c8e038aaf. Report an issue: GitHub.