{"record":{"id":"76cd11e006ee357b","repo":"medusajs/medusa","slug":"publishable-key-needs-to-have-a-sales-channel-conf","errorCode":null,"errorMessage":"Publishable key needs to have a sales channel configured","messagePattern":"Publishable key needs to have a sales channel configured","errorType":"validation","errorClass":"MedusaError","httpStatus":400,"severity":"error","filePath":"packages/medusa/src/api/utils/middlewares/products/filter-by-valid-sales-channels.ts","lineNumber":57,"sourceCode":"  }\n\n  if (idsFromPublishableKey?.length) {\n    return idsFromPublishableKey\n  }\n\n  return []\n}\n\n// Selection of sales channels happens in the following priority:\n// - If a publishable API key is passed, we take the sales channels attached to it and filter them down based on the query params\n// - If a sales channel id is passed through query params, we use that\n// - If not, we use the default sales channel for the store\nexport function filterByValidSalesChannels() {\n  return async (req: MedusaStoreRequest, _, next: NextFunction) => {\n    const salesChannelIds = transformAndValidateSalesChannelIds(req)\n\n    if (!salesChannelIds.length) {\n      throw new MedusaError(\n        MedusaError.Types.INVALID_DATA,\n        `Publishable key needs to have a sales channel configured`\n      )\n    }\n\n    req.filterableFields.sales_channel_id = salesChannelIds\n    next()\n  }\n}\n","sourceCodeStart":39,"sourceCodeEnd":67,"githubUrl":"https://github.com/medusajs/medusa/blob/5e06e544a296b9033f20f71f11c559f81a0e5739/packages/medusa/src/api/utils/middlewares/products/filter-by-valid-sales-channels.ts#L39-L67","documentation":"Thrown by filterByValidSalesChannels when the resolved sales channel list for a store request is empty — the publishable key has no sales channels attached and the request supplied no sales_channel_id either. Medusa cannot scope store product queries without at least one sales channel, so it fails fast with INVALID_DATA.","triggerScenarios":"Calling any /store/products endpoint with a publishable key that has zero sales channels configured, and no sales_channel_id query parameter as a fallback.","commonSituations":"Fresh Medusa setup where the seed script wasn't run or the default sales channel wasn't linked to the created publishable key; publishing a storefront key before assigning channels; deleted sales channels leaving the key empty.","solutions":["Attach at least one sales channel to the publishable key via Admin > Settings > Publishable API Keys (or /admin/api-keys update with sales_channel_id)","If no default sales channel exists, create one first (Admin > Settings > Sales Channels or the store endpoint)","Pass sales_channel_id explicitly in the request as a temporary workaround"],"exampleFix":"// before (key has no channels)\nGET /store/products\nx-publishable-api-key: pk_empty\n\n// after\n// attach sc_default to the key, then\nGET /store/products\nx-publishable-api-key: pk_with_channel\n// or pass one explicitly\nGET /store/products?sales_channel_id=sc_default","handlingStrategy":"validation","validationCode":"// storefront bootstrap check\nconst res = await fetch('/store/products?limit=1', {\n  headers: { 'x-publishable-api-key': PK },\n})\nif (res.status === 400) {\n  // key misconfigured: alert, or fallback to explicit channel\n  url.searchParams.set('sales_channel_id', DEFAULT_SC_ID)\n}","typeGuard":null,"tryCatchPattern":"try {\n  return await sdk.store.product.list()\n} catch (e) {\n  if (e.type === 'invalid_data' && /sales channel configured/.test(e.message)) {\n    return { error: 'publishable-key-misconfigured' }\n  }\n  throw e\n}","preventionTips":["Run a storefront bootstrap health check that lists products once at startup","Automate publishable-key→sales-channel linking in setup/seed scripts so a key is never left channel-less"],"tags":["sales-channel","publishable-key","store-api","configuration"],"backgroundTag":"missing-sales-channel-config","analyzedSha":"5e06e544a296b9033f20f71f11c559f81a0e5739","analyzedAt":"2026-08-27T07:24:39.599Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}