{"record":{"id":"ee9357eb57ab6139","repo":"medusajs/medusa","slug":"product-option-value-with-id-valueid-was-not","errorCode":null,"errorMessage":"Product option value with id \"${valueId}\" was not found for option with id \"${optionId}\"","messagePattern":"Product option value with id \"(.+?)\" was not found for option with id \"(.+?)\"","errorType":"http","errorClass":"MedusaError","httpStatus":404,"severity":"error","filePath":"packages/medusa/src/api/admin/product-options/[id]/values/[value_id]/route.ts","lineNumber":32,"sourceCode":"\nconst retrieveProductOptionValue = async (\n  req: AuthenticatedMedusaRequest<unknown, unknown>,\n  fields?: string[]\n): Promise<HttpTypes.AdminProductOptionValue> => {\n  // Ensure the value belongs to the option\n  const { value_id: valueId, id: optionId } = req.params\n  const query = req.scope.resolve(ContainerRegistrationKeys.QUERY)\n\n  const {\n    data: [product_option_value],\n  } = await query.graph({\n    entity: \"product_option_value\",\n    filters: { id: valueId, option_id: optionId },\n    fields: fields ?? [\"id\"],\n  })\n\n  if (!product_option_value) {\n    throw new MedusaError(\n      MedusaError.Types.NOT_FOUND,\n      `Product option value with id \"${valueId}\" was not found for option with id \"${optionId}\"`\n    )\n  }\n\n  return product_option_value\n}\n\n/**\n * @since 2.16.0\n */\nexport const GET = async (\n  req: AuthenticatedMedusaRequest<{}, HttpTypes.SelectParams>,\n  res: MedusaResponse<HttpTypes.AdminProductOptionValueResponse>\n) => {\n  const product_option_value = await retrieveProductOptionValue(\n    req,\n    req.queryConfig.fields","sourceCodeStart":14,"sourceCodeEnd":50,"githubUrl":"https://github.com/medusajs/medusa/blob/5e06e544a296b9033f20f71f11c559f81a0e5739/packages/medusa/src/api/admin/product-options/[id]/values/[value_id]/route.ts#L14-L50","documentation":"Thrown by retrieveProductOptionValue when the query for a product option value filtered by both valueId and optionId returns nothing. It enforces that the value actually belongs to the given option, so a mismatch reads the same as a missing record.","triggerScenarios":"Calling GET/POST/DELETE on /admin/product-options/:id/values/:value_id where the value id exists but belongs to a different option, or either id is wrong/deleted.","commonSituations":"Frontends keeping option and value ids in separate state and pairing them incorrectly after reordering, copying value ids between options during data imports, or stale ids after option regeneration.","solutions":["List the option's values (GET /admin/product-options/:id/values) and confirm the pairing before mutating","Rebuild the value/option id mapping in your client state from a fresh fetch","On 404, re-fetch the option and reselect the correct value id"],"exampleFix":"// before\nawait sdk.client.fetch(`/admin/product-options/${optionId}/values/${valueId}`, { method: \"DELETE\" })\n\n// after\nconst { values } = await fetchOptionValues(optionId)\nif (!values.some((v) => v.id === valueId)) {\n  throw new Error(`Value ${valueId} is not on option ${optionId}`)\n}\nawait sdk.client.fetch(`/admin/product-options/${optionId}/values/${valueId}`, { method: \"DELETE\" })","handlingStrategy":"validation","validationCode":"const { values } = await getOptionValues(optionId)\nif (!values.some((v) => v.id === valueId)) throw new Error(`Value ${valueId} not on option ${optionId}`)","typeGuard":"const belongsToOption = (v: { id: string; option_id?: string }, optionId: string) =>\n  v.option_id === optionId || !!v.option_id === false && valuesOf(optionId).includes(v.id)","tryCatchPattern":"try {\n  await deleteOptionValue(optionId, valueId)\n} catch (e: any) {\n  if (e.statusCode === 404) { await refetchOption(optionId); return }\n  throw e\n}","preventionTips":["Keep option/value pairs as one unit in client state","Re-fetch the option before mutations in stale UIs","Never copy value ids across options during imports"],"tags":["admin","product-options","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"}