nextauthjs/next-auth · error

User not found

Error message

User not found

What it means

MikroORM adapter's updateUser first fetches the user entity by data.id; if no row matches, it throws 'User not found' instead of silently failing. Unlike some adapters that upsert, this one requires the user to already exist for updateUser.

Source

Thrown at packages/adapter-mikro-orm/src/index.ts:123

      if (!user) return null

      return wrap(user).toObject()
    },
    async getUserByAccount(provider_providerAccountId) {
      const em = await getEM()
      const account = await em.findOne(AccountModel, {
        ...provider_providerAccountId,
      })
      if (!account) return null
      const user = await em.findOne(UserModel, { id: account.userId })
      if (!user) return null

      return wrap(user).toObject()
    },
    async updateUser(data) {
      const em = await getEM()
      const user = await em.findOne(UserModel, { id: data.id })
      if (!user) throw new Error("User not found")
      // `mergeObjects` (v5) was renamed to `mergeObjectProperties` (v6)
      wrap(user).assign(data, {
        mergeObjectProperties: true,
        ...{ mergeObjects: true },
      })
      await em.persistAndFlush(user)

      return wrap(user).toObject()
    },
    async deleteUser(id) {
      const em = await getEM()
      const user = await em.findOne(UserModel, { id })
      if (!user) return null
      await em.removeAndFlush(user)

      return wrap(user).toObject()
    },
    // @ts-expect-error

View on GitHub (pinned to a1a16a5a77)

Solutions

  1. Confirm a user row with that exact id exists (check type: number vs string id)
  2. Create the user first ( createUser) if updateUser is called for a possibly-new record, or wrap in existence check
  3. Fix id mapping between Auth.js identity and the User entity primary key
  4. Restore/check the database for deleted users and clear stale session cookies referencing them

Example fix

// before
await adapter.updateUser({ id: 42, name: 'New' })
// after
const existing = await adapter.getUser(42)
if (existing) await adapter.updateUser({ id: 42, name: 'New' })
Defensive patterns

Strategy: try-catch

Validate before calling

const user = await adapter.getUser(data.id)
if (!user) throw new Error(`Cannot update missing user ${data.id}`)

Type guard

function hasId(v: unknown): v is { id: string | number } {
  return typeof v === 'object' && v !== null && 'id' in v && v.id != null
}

Try / catch

try {
  await adapter.updateUser(data)
} catch (e) {
  if ((e as Error).message === 'User not found') {
    await adapter.createUser(data) // or log and skip
  } else throw e
}

Prevention

When it happens

Trigger: Calling updateUser with an id that has no User row, a stale id from a deleted user, or id being undefined/NaN due to bad mapping between Auth.js user.id and the ORM primary key (e.g., numeric id vs string).

Common situations: Auth.js updating a user whose row was manually deleted from the DB; switching the User primary key type (autoincrement int vs uuid) without migrating; passing an email instead of id by mistake; database reset between environments.

Understand the failure class

Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.

Related errors


AI-assisted analysis of nextauthjs/next-auth@a1a16a5a77 (2026-08-28). Data as JSON: /api/errors/29571c9c76bad5ee. Report an issue: GitHub.