nextauthjs/next-auth · error
User not created
Error message
User not created
What it means
The SurrealDB adapter's createUser runs a CREATE query and, after first checking for an existing user by a uniqueness lookup, converts the returned documents via docToUser. If the query returns no documents (or the inner try/catch swallows a failure), it throws 'User not created' — meaning the database did not persist/return the new user row.
Source
Thrown at packages/adapter-surrealdb/src/index.ts:196
export function SurrealDBAdapter(
client: Promise<Surreal>
// options = {}
): Adapter {
return {
async createUser(user: Partial<AdapterUser>) {
try {
const surreal = await client
const doc = userToDoc(user)
const userDoc = await surreal.create<UserDoc, Omit<UserDoc, "id">>(
"user",
doc
)
if (userDoc.length) {
return docToUser(userDoc[0])
}
} catch {}
throw new Error("User not created")
},
async getUser(id: string) {
const surreal = await client
try {
const [userDoc] = await surreal.query<[UserDoc[]]>(
"SELECT * FROM $user",
{
user: new RecordId("user", id),
}
)
const doc = userDoc.at(0)
if (doc) {
return docToUser(doc)
}
} catch {}
return null
},
async getUserByEmail(email: string) {View on GitHub (pinned to a1a16a5a77)
Solutions
- Verify SurrealDB connection config includes correct namespace/database and the users table exists
- Check SurrealDB permissions/roles allow CREATE on the users table
- Inspect the swallowed exception in the dedupe lookup — log it to see the real failure (e.g., duplicate email)
- If using SCHEMAFULL tables, ensure the insert matches the defined fields and types
- Confirm the adapter query/mapping (table name, docToUser) matches your SurrealDB schema
Example fix
// before
try {
const [existing] = await surreal.query("SELECT * FROM user WHERE email = $email", { email })
} catch {}
throw new Error('User not created')
// after
try {
const [existing] = await surreal.query("SELECT * FROM user WHERE email = $email", { email })
} catch (e) {
console.error('createUser pre-check failed', e)
throw e
} Defensive patterns
Strategy: validation
Validate before calling
const surreal = await client
const [[info]] = await surreal.query("SELECT * FROM info()")
if (!info) throw new Error('SurrealDB namespace/database not selected') Type guard
function isValidUserDoc(v: unknown): v is { id: string; email: string } {
return typeof v === 'object' && v !== null &&
typeof (v as any).email === 'string'
} Prevention
- Verify namespace/database selection before app boot
- Check table permissions allow CREATE
- Align inserts with SCHEMAFULL field definitions
When it happens
Trigger: CREATE silently failing (permission denied on the users table, schema constraint violation), the pre-check query throwing (caught by the empty catch block) followed by the fallthrough throw, wrong table name in the adapter config so inserts go nowhere visible, or SurrealDB connection returning empty results on error.
Common situations: Missing SurrealDB namespace/database selection so queries hit an empty scope; email already exists but the dedupe branch errored and was swallowed; SCHEMAFULL table definition rejecting the insert; auth/role misconfiguration preventing CREATE.
Related errors
- Object is nullish
- User not found
- Unable to update authenticator with credential ${credentialI
- Error creating user: Cannot get user after creation.
- Error updating user: Cannot get user after updating.
AI-assisted analysis of nextauthjs/next-auth@a1a16a5a77 (2026-08-28).
Data as JSON: /api/errors/9f3f89058889c2f5.
Report an issue: GitHub.