{"record":{"id":"ce1cdcece3bfaced","repo":"medusajs/medusa","slug":"policy-with-id-req-params-id-not-found-ce1cdc","errorCode":null,"errorMessage":"Policy with id \"${req.params.id}\" not found","messagePattern":"Policy with id \"(.+?)\" not found","errorType":"exception","errorClass":"MedusaError","httpStatus":404,"severity":"error","filePath":"packages/medusa/src/api/admin/rbac/policies/[id]/route.ts","lineNumber":63,"sourceCode":"\n/**\n * @ignore\n * @featureFlag rbac\n */\nexport const POST = async (\n  req: AuthenticatedMedusaRequest<AdminUpdateRbacPolicyType>,\n  res: MedusaResponse\n) => {\n  const query = req.scope.resolve(ContainerRegistrationKeys.QUERY)\n  const { data: existing } = await query.graph({\n    entity: \"rbac_policy\",\n    filters: { id: req.params.id },\n    fields: [\"id\"],\n  })\n\n  const existingPolicy = existing[0]\n  if (!existingPolicy) {\n    throw new MedusaError(\n      MedusaError.Types.NOT_FOUND,\n      `Policy with id \"${req.params.id}\" not found`\n    )\n  }\n\n  const { result } = await updateRbacPoliciesWorkflow(req.scope).run({\n    input: {\n      selector: { id: req.params.id },\n      update: req.validatedBody,\n    },\n  })\n\n  const { data: policies } = await query.graph({\n    entity: \"rbac_policy\",\n    filters: { id: result[0].id },\n    fields: req.queryConfig.fields,\n  })\n","sourceCodeStart":45,"sourceCodeEnd":81,"githubUrl":"https://github.com/medusajs/medusa/blob/5e06e544a296b9033f20f71f11c559f81a0e5739/packages/medusa/src/api/admin/rbac/policies/[id]/route.ts#L45-L81","documentation":"Thrown by POST /admin/rbac/policies/:id when the pre-update existence check (fields: [\"id\"]) returns no policy. Like other update routes, it verifies the policy exists before running updateRbacPoliciesWorkflow.","triggerScenarios":"Updating a policy id that does not exist or was concurrently deleted via POST /admin/rbac/policies/:id with an update body.","commonSituations":"Two admins editing RBAC policies simultaneously, policy regeneration between load and save, or stale ids in permission-sync scripts.","solutions":["Re-fetch policies and merge your change onto the current version before updating","On 404, recreate the policy instead of updating","Refresh RBAC state after bulk policy imports/regenerations"],"exampleFix":"// before\nawait sdk.client.fetch(`/admin/rbac/policies/${id}`, { method: \"POST\", body: updatedPolicy })\n\n// after\ntry {\n  await sdk.client.fetch(`/admin/rbac/policies/${id}`, { method: \"POST\", body: updatedPolicy })\n} catch (e) {\n  if (e.statusCode === 404) { await sdk.client.fetch(\"/admin/rbac/policies\", { method: \"POST\", body: updatedPolicy }); return }\n  throw e\n}","handlingStrategy":"try-catch","validationCode":"const { policies } = await sdk.client.fetch(\"/admin/rbac/policies\", { query: { id: [policyId] } })\nif (policies.length === 0) throw new Error(`Policy ${policyId} gone; recreate instead of update`)","typeGuard":null,"tryCatchPattern":"try {\n  await updatePolicy(id, patch)\n} catch (e: any) {\n  if (e.statusCode === 404) { await createPolicy(patch); return }\n  throw e\n}","preventionTips":["Merge edits onto freshly fetched policy state","Use upsert semantics in provisioning scripts","Refresh RBAC state after bulk policy changes"],"tags":["admin","rbac","policies","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"}