nextauthjs/next-auth · error
[updateUser] Failed to fetch updated user
Error message
[updateUser] Failed to fetch updated user
What it means
After merging the partial user into Firestore with userRef.set(partialUser, { merge: true }), the adapter reads the document back and throws '[updateUser] Failed to fetch updated user' if the read returns nothing. Since a set with merge should always leave a readable doc, this signals the document disappeared between write and read or the read helper misreports the result.
Source
Thrown at packages/adapter-firebase/src/index.ts:136
const account = await getOneDoc(
C.accounts
.where("provider", "==", provider)
.where(mapper.toDb("providerAccountId"), "==", providerAccountId)
)
if (!account) return null
return await getDoc(C.users.doc(account.userId))
},
async updateUser(partialUser) {
if (!partialUser.id) throw new Error("[updateUser] Missing id")
const userRef = C.users.doc(partialUser.id)
await userRef.set(partialUser, { merge: true })
const user = await getDoc(userRef)
if (!user) throw new Error("[updateUser] Failed to fetch updated user")
return user
},
async deleteUser(userId) {
await db.runTransaction(async (transaction) => {
const accounts = await C.accounts
.where(mapper.toDb("userId"), "==", userId)
.get()
const sessions = await C.sessions
.where(mapper.toDb("userId"), "==", userId)
.get()
transaction.delete(C.users.doc(userId))
accounts.forEach((account) => transaction.delete(account.ref))
sessions.forEach((session) => transaction.delete(session.ref))
})View on GitHub (pinned to a1a16a5a77)
Solutions
- Audit Firestore triggers/extensions on the users collection that might delete or restrict the doc right after writes.
- Fix the custom getDoc helper to honor snapshot existence and return mapped data correctly.
- Verify security rules permit read access for the adapter's credentials on the users collection.
- Serialize user-deletion and user-update flows to avoid the delete/update race.
Example fix
// before
await userRef.set(partialUser, { merge: true })
const user = await getDoc(userRef)
if (!user) throw new Error('[updateUser] Failed to fetch updated user')
// after
await userRef.set(partialUser, { merge: true })
const snap = await userRef.get()
if (!snap.exists) throw new Error('[updateUser] Failed to fetch updated user')
const user = mapper.fromDb({ id: snap.id, ...snap.data() }) Defensive patterns
Strategy: try-catch
Validate before calling
const before = await userRef.get()
if (!before.exists) throw new Error(`User doc ${partialUser.id} missing before update`) Type guard
function isPopulatedDoc<T>(d: T | undefined | null): d is T {
return d !== undefined && d !== null
} Try / catch
try {
await adapter.updateUser({ id, ...patch })
} catch (e) {
if ((e as Error).message.includes('Failed to fetch updated user')) {
console.warn(`Update on ${id} succeeded but readback failed; check triggers/rules`)
return
}
throw e
} Prevention
- Audit onWrite/onDelete Cloud Functions and extensions on the users collection.
- Avoid running deleteUser and updateUser concurrently for the same user.
- Have the getDoc helper honor snapshot.exists and return mapped data.
When it happens
Trigger: A Firestore security rule, extension, or Cloud Function (e.g. onWrite cleanup) removes/locks the document immediately after the merge; a custom getDoc wrapper returns undefined despite doc existence; concurrent deleteUser racing the update.
Common situations: Delete-user Cloud Functions triggered by auth user deletion that also purge Firestore docs while a session update is in flight; rules denying the follow-up read for the adapter's identity; emulator restarts losing data mid-test.
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
- [createUser] Failed to fetch created user
- [createSession] Failed to fetch created session
- [updateSession] Failed to fetch updated session
- No user found.
- Authenticator not found.
AI-assisted analysis of nextauthjs/next-auth@a1a16a5a77 (2026-08-28).
Data as JSON: /api/errors/3f8bfeaa2b3474b2.
Report an issue: GitHub.