{"record":{"id":"e63382d74aeb8bfa","repo":"medusajs/medusa","slug":"not-found-e63382","errorCode":"not_found","errorMessage":"${entityName} ${identifier} not found","messagePattern":"(.+?) (.+?) not found","errorType":"error_code","errorClass":"MedusaError","httpStatus":404,"severity":"error","filePath":"packages/plugins/loyalty/src/workflows/common/steps/validate-presence-of.ts","lineNumber":41,"sourceCode":" * This step validates that an entity is present. It throws a NOT_FOUND error if\n * the entity is falsy.\n *\n * @example\n * const data = validatePresenceOfStep({\n *   entity: customer,\n *   entityName: \"Customer\",\n *   identifier: \"cust_123\",\n * })\n */\nexport const validatePresenceOfStep = createStep(\n  \"validate-presence-of\",\n  async function ({\n    entity,\n    entityName,\n    identifier,\n  }: ValidatePresenceOfStepInput) {\n    if (!entity) {\n      throw new MedusaError(\n        MedusaError.Types.NOT_FOUND,\n        `${entityName} ${identifier} not found`\n      );\n    }\n  }\n);\n","sourceCodeStart":23,"sourceCodeEnd":48,"githubUrl":"https://github.com/medusajs/medusa/blob/5e06e544a296b9033f20f71f11c559f81a0e5739/packages/plugins/loyalty/src/workflows/common/steps/validate-presence-of.ts#L23-L48","documentation":"Generic NOT_FOUND assertion step used across loyalty workflows to assert that a queried entity loaded successfully. The message interpolates the entity name and identifier passed into the step, e.g. 'Gift card gc_123 not found'.","triggerScenarios":"Any workflow that uses validatePresenceOfStepStep where the preceding query (useQueryGraphStep or service retrieve) returned null/undefined — typically a wrong or deleted id/code supplied as workflow input.","commonSituations":"Passing an id from a different environment (staging id in prod), operating on a soft-deleted record, or a typo in route params that flow into the workflow input.","solutions":["Check the identifier exists before invoking the workflow (query by id first)","Confirm you are querying the same environment/database the entity lives in","If the entity may be soft-deleted, include deleted records filter or restore it before retrying"],"exampleFix":"// before\nawait someWorkflow(container).run({ input: { id } })\n// after\nconst { data } = await query.graph({ entity: \"gift_card\", filters: { id }, fields: [\"id\"] })\nif (!data.length) throw new MedusaError(MedusaError.Types.NOT_FOUND, `Gift card ${id} not found`)\nawait someWorkflow(container).run({ input: { id } })","handlingStrategy":"validation","validationCode":"const { data } = await query.graph({ entity, filters: { id: identifier }, fields: [\"id\"] })\nif (!data.length) throw new MedusaError(MedusaError.Types.NOT_FOUND, `${entityName} ${identifier} not found`)","typeGuard":"const isPresent = <T,>(v: T | null | undefined): v is T => v !== null && v !== undefined","tryCatchPattern":"try { await workflow(container).run({ input }) } catch (e) { if (e instanceof MedusaError && e.type === \"not_found\") return handle404(e); throw e }","preventionTips":["Validate ids at the API layer before starting workflows","Return 404 early from routes instead of letting workflow steps fail"],"tags":["medusa","loyalty","not-found","workflow-step","validation"],"backgroundTag":"entity-not-found","analyzedSha":"5e06e544a296b9033f20f71f11c559f81a0e5739","analyzedAt":"2026-08-27T07:24:39.599Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}