medusajs/medusa · error · MedusaError

not_found

not_found

Error message

${entityName} ${identifier} not found

What it means

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'.

Source

Thrown at packages/plugins/loyalty/src/workflows/common/steps/validate-presence-of.ts:41

 * This step validates that an entity is present. It throws a NOT_FOUND error if
 * the entity is falsy.
 *
 * @example
 * const data = validatePresenceOfStep({
 *   entity: customer,
 *   entityName: "Customer",
 *   identifier: "cust_123",
 * })
 */
export const validatePresenceOfStep = createStep(
  "validate-presence-of",
  async function ({
    entity,
    entityName,
    identifier,
  }: ValidatePresenceOfStepInput) {
    if (!entity) {
      throw new MedusaError(
        MedusaError.Types.NOT_FOUND,
        `${entityName} ${identifier} not found`
      );
    }
  }
);

View on GitHub (pinned to 5e06e544a2)

Solutions

  1. Check the identifier exists before invoking the workflow (query by id first)
  2. Confirm you are querying the same environment/database the entity lives in
  3. If the entity may be soft-deleted, include deleted records filter or restore it before retrying

Example fix

// before
await someWorkflow(container).run({ input: { id } })
// after
const { data } = await query.graph({ entity: "gift_card", filters: { id }, fields: ["id"] })
if (!data.length) throw new MedusaError(MedusaError.Types.NOT_FOUND, `Gift card ${id} not found`)
await someWorkflow(container).run({ input: { id } })
Defensive patterns

Strategy: validation

Validate before calling

const { data } = await query.graph({ entity, filters: { id: identifier }, fields: ["id"] })
if (!data.length) throw new MedusaError(MedusaError.Types.NOT_FOUND, `${entityName} ${identifier} not found`)

Type guard

const isPresent = <T,>(v: T | null | undefined): v is T => v !== null && v !== undefined

Try / catch

try { await workflow(container).run({ input }) } catch (e) { if (e instanceof MedusaError && e.type === "not_found") return handle404(e); throw e }

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.

Related errors


AI-assisted analysis of medusajs/medusa@5e06e544a2 (2026-08-27). Data as JSON: /api/errors/e63382d74aeb8bfa. Report an issue: GitHub.