{"record":{"id":"7565d61d2af94640","repo":"medusajs/medusa","slug":"promotion-with-id-or-code-idorcode-was-not-fou","errorCode":null,"errorMessage":"Promotion with id or code: ${idOrCode} was not found","messagePattern":"Promotion with id or code: (.+?) was not found","errorType":"exception","errorClass":"MedusaError","httpStatus":404,"severity":"error","filePath":"packages/medusa/src/api/admin/promotions/[id]/route.ts","lineNumber":33,"sourceCode":"import { AdditionalData, HttpTypes } from \"@medusajs/framework/types\"\n\nexport const GET = async (\n  req: AuthenticatedMedusaRequest<HttpTypes.AdminGetPromotionParams>,\n  res: MedusaResponse<HttpTypes.AdminPromotionResponse>\n) => {\n  const idOrCode = req.params.id\n  const remoteQuery = req.scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY)\n  const queryObject = remoteQueryObjectFromString({\n    entryPoint: \"promotion\",\n    variables: {\n      filters: { $or: [{ id: idOrCode }, { code: idOrCode }] },\n    },\n    fields: req.queryConfig.fields,\n  })\n\n  const [promotion] = await remoteQuery(queryObject)\n  if (!promotion) {\n    throw new MedusaError(\n      MedusaError.Types.NOT_FOUND,\n      `Promotion with id or code: ${idOrCode} was not found`\n    )\n  }\n\n  res.status(200).json({ promotion })\n}\n\nexport const POST = async (\n  req: AuthenticatedMedusaRequest<\n    HttpTypes.AdminUpdatePromotion & AdditionalData,\n    HttpTypes.AdminGetPromotionParams\n  >,\n  res: MedusaResponse<HttpTypes.AdminPromotionResponse>\n) => {\n  const { additional_data, ...rest } = req.validatedBody\n  const updatePromotions = updatePromotionsWorkflow(req.scope)\n  const promotionsData = [","sourceCodeStart":15,"sourceCodeEnd":51,"githubUrl":"https://github.com/medusajs/medusa/blob/5e06e544a296b9033f20f71f11c559f81a0e5739/packages/medusa/src/api/admin/promotions/[id]/route.ts#L15-L51","documentation":"Thrown by GET /admin/promotions/:id when the remoteQuery for the promotion returns nothing. The route intentionally resolves by id OR code, so the failure means neither a promotion id nor a promotion code matched the path param.","triggerScenarios":"Calling GET /admin/promotions/promo_123 (or /admin/promotions/SUMMER10) where neither an id nor a code with that value exists, or the promotion was deleted.","commonSituations":"Passing a code that was renamed or expired-and-deleted, mixing up campaign ids with promotion codes, or stale references after promotion re-imports.","solutions":["List promotions (GET /admin/promotions) and confirm the id/code","If the code was renamed, use the updated code from the list response","In checkout code that applies codes, treat this 404 as 'invalid code' rather than an exception"],"exampleFix":"// before\nconst { promotion } = await sdk.admin.promotion.retrieve(code)\n\n// after\nconst { promotions } = await sdk.admin.promotion.list({ q: code })\nconst promo = promotions.find((p) => p.code === code || p.id === code)\nif (!promo) throw new Error(`No promotion for ${code}`)","handlingStrategy":"try-catch","validationCode":"const { promotions } = await sdk.admin.promotion.list({ q: idOrCode })\nif (!promotions.some((p) => p.id === idOrCode || p.code === idOrCode)) {\n  throw new Error(`No promotion matches ${idOrCode}`)\n}","typeGuard":"const isPromotion = (v: unknown): v is HttpTypes.AdminPromotion =>\n  !!v && typeof v === \"object\" && \"id\" in v && \"code\" in v","tryCatchPattern":"try {\n  return await getPromotion(idOrCode)\n} catch (e: any) {\n  if (e.statusCode === 404) return { valid: false, reason: \"unknown code\" }\n  throw e\n}","preventionTips":["Treat promotion 404 as 'invalid code' UX, not an exception","Don't cache promotion codes across renames","Verify codes after promotion re-imports"],"tags":["admin","promotions","not-found","rest-api"],"backgroundTag":"resource-not-found","analyzedSha":"5e06e544a296b9033f20f71f11c559f81a0e5739","analyzedAt":"2026-08-27T07:24:39.599Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}