{"record":{"id":"ab3aefa5de3f5f18","repo":"medusajs/medusa","slug":"product-tag-with-id-req-params-id-not-found","errorCode":null,"errorMessage":"Product tag with id \"${req.params.id}\" not found","messagePattern":"Product tag with id \"(.+?)\" not found","errorType":"exception","errorClass":"MedusaError","httpStatus":404,"severity":"error","filePath":"packages/medusa/src/api/admin/product-tags/[id]/route.ts","lineNumber":44,"sourceCode":"  res.status(200).json({ product_tag: productTag })\n}\n\nexport const POST = async (\n  req: AuthenticatedMedusaRequest<\n    HttpTypes.AdminUpdateProductTag,\n    HttpTypes.AdminProductTagParams\n  >,\n  res: MedusaResponse<HttpTypes.AdminProductTagResponse>\n) => {\n  const existingProductTag = await refetchEntity({\n    entity: \"product_tag\",\n    idOrFilter: req.params.id,\n    scope: req.scope,\n    fields: [\"id\"],\n  })\n\n  if (!existingProductTag) {\n    throw new MedusaError(\n      MedusaError.Types.NOT_FOUND,\n      `Product tag with id \"${req.params.id}\" not found`\n    )\n  }\n\n  const { result } = await updateProductTagsWorkflow(req.scope).run({\n    input: {\n      selector: { id: req.params.id },\n      update: req.validatedBody,\n    },\n  })\n\n  const productTag = await refetchEntity({\n    entity: \"product_tag\",\n    idOrFilter: result[0].id,\n    scope: req.scope,\n    fields: req.queryConfig.fields,\n  })","sourceCodeStart":26,"sourceCodeEnd":62,"githubUrl":"https://github.com/medusajs/medusa/blob/5e06e544a296b9033f20f71f11c559f81a0e5739/packages/medusa/src/api/admin/product-tags/[id]/route.ts#L26-L62","documentation":"Thrown by POST /admin/product-tags/:id when the pre-update existence check (refetch with fields [\"id\"]) finds no product tag. The route verifies the tag exists before running updateProductTagsWorkflow.","triggerScenarios":"Updating a product tag id that was deleted or never existed, e.g. POST /admin/product-tags/ptag_123 with a body update.","commonSituations":"Bulk-tag tools caching old tag ids, tags deleted by another admin mid-session, or ids from a different environment copied into scripts.","solutions":["List tags (GET /admin/product-tags) and confirm the id before updating","If the tag was deleted, create it again instead of updating","Refresh cached tag lists in bulk-edit tooling before applying changes"],"exampleFix":"// before\nawait sdk.admin.productTag.update(tagId, { value: \"new-tag\" })\n\n// after\nconst { product_tags } = await sdk.admin.productTag.list()\nif (!product_tags.some((t) => t.id === tagId)) {\n  return sdk.admin.productTag.create({ value: \"new-tag\" })\n}\nawait sdk.admin.productTag.update(tagId, { value: \"new-tag\" })","handlingStrategy":"validation","validationCode":"const { product_tags } = await sdk.admin.productTag.list({ id: [tagId] })\nif (product_tags.length === 0) throw new Error(`Tag ${tagId} not found`)","typeGuard":"const isProductTag = (v: unknown): v is HttpTypes.AdminProductTag =>\n  !!v && typeof v === \"object\" && \"id\" in v && \"value\" in v","tryCatchPattern":"try {\n  await sdk.admin.productTag.update(tagId, patch)\n} catch (e: any) {\n  if (e.statusCode === 404) { await sdk.admin.productTag.create(patch); return }\n  throw e\n}","preventionTips":["Bulk editors should refresh tag lists before applying","Use upsert semantics (create on 404) in sync tools","Invalidate tag caches after deletions"],"tags":["admin","product-tags","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"}