nextauthjs/next-auth · error

No user found.

Error message

No user found.

What it means

After performing the UPDATE, the adapter re-selects the user row by id; if no row comes back it throws 'No user found.' instead of returning undefined. This means the update targeted an id that does not exist in the users table.

Source

Thrown at packages/adapter-drizzle/src/lib/mysql.ts:227

      } | null>
    },
    async updateUser(data: Partial<AdapterUser> & Pick<AdapterUser, "id">) {
      if (!data.id) {
        throw new Error("No user id.")
      }

      await client
        .update(usersTable)
        .set(data)
        .where(eq(usersTable.id, data.id))

      const [result] = await client
        .select()
        .from(usersTable)
        .where(eq(usersTable.id, data.id))

      if (!result) {
        throw new Error("No user found.")
      }

      return result as Awaitable<AdapterUser>
    },
    async updateSession(
      data: Partial<AdapterSession> & Pick<AdapterSession, "sessionToken">
    ) {
      await client
        .update(sessionsTable)
        .set(data)
        .where(eq(sessionsTable.sessionToken, data.sessionToken))

      return client
        .select()
        .from(sessionsTable)
        .where(eq(sessionsTable.sessionToken, data.sessionToken))
        .then((res) => res[0])
    },

View on GitHub (pinned to a1a16a5a77)

Solutions

  1. Verify the user exists first via getUser(id) before updating.
  2. Confirm the drizzle client connects to the database/schema containing your users table.
  3. Check the id value/type matches what is stored (avoid silent MySQL coercions).
  4. Insert the user first if the flow expects createUser to have run.

Example fix

// before
await adapter.updateUser({ id: staleId, name: 'new' })
// after
const user = await adapter.getUser(staleId)
if (!user) throw new Error(`User ${staleId} does not exist`)
await adapter.updateUser({ id: staleId, name: 'new' })
Defensive patterns

Strategy: validation

Validate before calling

const user = await adapter.getUser(id)
if (!user) throw new Error(`No user with id ${id} to update`)

Type guard

function isExistingUser(u: AdapterUser | null): u is AdapterUser {
  return u !== null && typeof u.id === 'string'
}

Try / catch

try {
  const updated = await adapter.updateUser({ id, ...changes })
} catch (e) {
  if (e instanceof Error && e.message === 'No user found.') {
    // the row vanished or id is wrong; handle as 404, not 500
  }
  throw e
}

Prevention

When it happens

Trigger: adapter.updateUser({ id, ... }) where no user with that id exists in the MySQL users table (stale/deleted id, wrong database, or id type mismatch).

Common situations: Updating a user that was deleted in another request, pointing the drizzle client at a different database/schema than the one holding users, or string-vs-number id coercion issues in MySQL.

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/94b993b78fc58e9e. Report an issue: GitHub.