medusajs/medusa · error · MedusaError
Product type with id "${req.params.id}" not found
Error message
Product type with id "${req.params.id}" not found What it means
Thrown by POST /admin/product-types/:id when the existence refetch of the product type returns nothing before updateProductTypesWorkflow runs. The route guards against updating non-existent types.
Source
Thrown at packages/medusa/src/api/admin/product-types/[id]/route.ts:43
res.status(200).json({ product_type: productType })
}
export const POST = async (
req: AuthenticatedMedusaRequest<
HttpTypes.AdminUpdateProductType,
HttpTypes.AdminProductTypeParams
>,
res: MedusaResponse<HttpTypes.AdminProductTypeResponse>
) => {
const existingProductType = await refetchProductType(
req.params.id,
req.scope,
["id"]
)
if (!existingProductType) {
throw new MedusaError(
MedusaError.Types.NOT_FOUND,
`Product type with id "${req.params.id}" not found`
)
}
const { result } = await updateProductTypesWorkflow(req.scope).run({
input: {
selector: { id: req.params.id },
update: req.validatedBody,
},
})
const productType = await refetchProductType(
result[0].id,
req.scope,
req.queryConfig.fields
)
View on GitHub (pinned to 5e06e544a2)
Solutions
- List product types (GET /admin/product-types) to verify the id
- Recreate the type if it was deleted and you still need it
- Invalidate cached type lists after deletions
Example fix
// before
await sdk.admin.productType.update(typeId, { value: "New Type" })
// after
const { product_types } = await sdk.admin.productType.list()
if (!product_types.some((t) => t.id === typeId)) {
throw new Error(`Product type ${typeId} missing; create it first`)
}
await sdk.admin.productType.update(typeId, { value: "New Type" }) Defensive patterns
Strategy: validation
Validate before calling
const { product_types } = await sdk.admin.productType.list({ id: [typeId] })
if (product_types.length === 0) throw new Error(`Type ${typeId} not found`) Type guard
const isProductType = (v: unknown): v is HttpTypes.AdminProductType => !!v && typeof v === "object" && "id" in v && "value" in v
Try / catch
try {
await sdk.admin.productType.update(typeId, patch)
} catch (e: any) {
if (e.statusCode === 404) { await sdk.admin.productType.create(patch); return }
throw e
} Prevention
- Re-sync type picklists after deletions
- Verify ids after db re-seeds
- Upsert instead of blind update in integrations
When it happens
Trigger: Calling POST /admin/product-types/ptyp_123 with an update body for a type id that does not exist or was deleted.
Common situations: Product type picklists cached client-side after deletion, ids from seed data after a db reset, or cross-environment id copying.
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 tag with id "${req.params.id}" not found
AI-assisted analysis of medusajs/medusa@5e06e544a2 (2026-08-27).
Data as JSON: /api/errors/881424852add4bde.
Report an issue: GitHub.