medusajs/medusa · error · MedusaError
Product tag with id "${req.params.id}" not found
Error message
Product tag with id "${req.params.id}" not found What it means
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.
Source
Thrown at packages/medusa/src/api/admin/product-tags/[id]/route.ts:44
res.status(200).json({ product_tag: productTag })
}
export const POST = async (
req: AuthenticatedMedusaRequest<
HttpTypes.AdminUpdateProductTag,
HttpTypes.AdminProductTagParams
>,
res: MedusaResponse<HttpTypes.AdminProductTagResponse>
) => {
const existingProductTag = await refetchEntity({
entity: "product_tag",
idOrFilter: req.params.id,
scope: req.scope,
fields: ["id"],
})
if (!existingProductTag) {
throw new MedusaError(
MedusaError.Types.NOT_FOUND,
`Product tag with id "${req.params.id}" not found`
)
}
const { result } = await updateProductTagsWorkflow(req.scope).run({
input: {
selector: { id: req.params.id },
update: req.validatedBody,
},
})
const productTag = await refetchEntity({
entity: "product_tag",
idOrFilter: result[0].id,
scope: req.scope,
fields: req.queryConfig.fields,
})View on GitHub (pinned to 5e06e544a2)
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
Example fix
// before
await sdk.admin.productTag.update(tagId, { value: "new-tag" })
// after
const { product_tags } = await sdk.admin.productTag.list()
if (!product_tags.some((t) => t.id === tagId)) {
return sdk.admin.productTag.create({ value: "new-tag" })
}
await sdk.admin.productTag.update(tagId, { value: "new-tag" }) Defensive patterns
Strategy: validation
Validate before calling
const { product_tags } = await sdk.admin.productTag.list({ id: [tagId] })
if (product_tags.length === 0) throw new Error(`Tag ${tagId} not found`) Type guard
const isProductTag = (v: unknown): v is HttpTypes.AdminProductTag => !!v && typeof v === "object" && "id" in v && "value" in v
Try / catch
try {
await sdk.admin.productTag.update(tagId, patch)
} catch (e: any) {
if (e.statusCode === 404) { await sdk.admin.productTag.create(patch); return }
throw e
} Prevention
- Bulk editors should refresh tag lists before applying
- Use upsert semantics (create on 404) in sync tools
- Invalidate tag caches after deletions
When it happens
Trigger: Updating a product tag id that was deleted or never existed, e.g. POST /admin/product-tags/ptag_123 with a body update.
Common situations: Bulk-tag tools caching old tag ids, tags deleted by another admin mid-session, or ids from a different environment copied into scripts.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- Invite with id: ${id} was not found
- Price list with id: ${id} was not found
- Product category with id: ${req.params.id} was not found
- Product option value with id "${valueId}" was not found for
- Product type with id "${req.params.id}" not found
AI-assisted analysis of medusajs/medusa@5e06e544a2 (2026-08-27).
Data as JSON: /api/errors/ab3aefa5de3f5f18.
Report an issue: GitHub.