{"record":{"id":"a3d5bc2f74314a76","repo":"nextauthjs/next-auth","slug":"authenticator-not-created","errorCode":null,"errorMessage":"Authenticator not created","messagePattern":"Authenticator not created","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/adapter-surrealdb/src/index.ts","lineNumber":503,"sourceCode":"        )\n        if (accountsDoc.length) {\n          return docToAccount(accountsDoc[0])\n        }\n      } catch {}\n      return null\n    },\n    async createAuthenticator(authenticator: AdapterAuthenticator) {\n      try {\n        const surreal = await client\n        const authenticatorDoc = await surreal.create<\n          AuthenticatorDoc,\n          Omit<AuthenticatorDoc, \"id\">\n        >(\"authenticator\", authenticatorToDoc(authenticator))\n        if (authenticatorDoc.length) {\n          return docToAuthenticator(authenticatorDoc[0])\n        }\n      } catch {}\n      throw new Error(\"Authenticator not created\")\n    },\n    async getAuthenticator(credentialId: AdapterAuthenticator[\"credentialID\"]) {\n      const surreal = await client\n      try {\n        const [authenticatorDoc] = await surreal.query<[AuthenticatorDoc[]]>(\n          `SELECT * FROM authenticator WHERE credentialID = $cid LIMIT 1`,\n          {\n            cid: credentialId,\n          }\n        )\n        if (authenticatorDoc.length) {\n          return docToAuthenticator(authenticatorDoc[0])\n        }\n      } catch {}\n      return null\n    },\n    async listAuthenticatorsByUserId(userId: AdapterAuthenticator[\"userId\"]) {\n      const surreal = await client","sourceCodeStart":485,"sourceCodeEnd":521,"githubUrl":"https://github.com/nextauthjs/next-auth/blob/a1a16a5a7780488c7449feece410033f445d0b31/packages/adapter-surrealdb/src/index.ts#L485-L521","documentation":"createAuthenticator() persists a WebAuthn/passkey authenticator. If the SurrealDB create throws or returns an empty array, the adapter throws 'Authenticator not created', discarding the root cause in an empty catch.","triggerScenarios":"surreal.create('authenticator', ...) fails (connectivity, permissions, schema) or yields zero rows; authenticatorToDoc produced invalid fields (e.g. credentialID/credentialPublicKey malformed).","commonSituations":"Passkey registration failing because the authenticator table lacks CREATE permission; SurrealDB misconfigured namespace/database; duplicate credentialID being inserted.","solutions":["Verify SurrealDB is reachable and the `authenticator` table exists and is writable","Check permissions allow CREATE on the authenticator table for the adapter user","Ensure the WebAuthn credential payload (credentialID, publicKey, counter) is complete before the call","Add temporary logging inside the try to expose the underlying error"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"if (!authenticator?.credentialID || !authenticator?.credentialPublicKey) {\n  throw new Error('Authenticator payload missing credentialID/publicKey')\n}\nawait adapter.createAuthenticator(authenticator)","typeGuard":"function isValidAuthenticator(a: AdapterAuthenticator): boolean {\n  return typeof a.credentialID === 'string' && a.credentialID.length > 0 &&\n    a.credentialPublicKey != null && typeof a.userId === 'string'\n}","tryCatchPattern":"try {\n  return await adapter.createAuthenticator(authenticator)\n} catch (e) {\n  if (e.message === 'Authenticator not created') {\n    console.error('WebAuthn authenticator insert failed — check SurrealDB', e)\n  }\n  throw e\n}","preventionTips":["Validate WebAuthn registration payload before persisting","Grant CREATE on the authenticator table to the adapter role","Watch for duplicate credentialID inserts"],"tags":["adapter","webauthn","surrealdb"],"backgroundTag":"adapter-write-failed","analyzedSha":"a1a16a5a7780488c7449feece410033f445d0b31","analyzedAt":"2026-08-28T21:52:38.200Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}