[GH-ISSUE #7141] OAuth Proxy: Failed query: delete from "verification" where "verification"."id" #10745

Open
opened 2026-04-13 07:04:06 -05:00 by GiteaMirror · 6 comments
Owner

Originally created by @mimamuh on GitHub (Jan 5, 2026).
Original GitHub issue: https://github.com/better-auth/better-auth/issues/7141

Originally assigned to: @bytaesu on GitHub.

Is this suited for github?

  • Yes, this is suited for github

To Reproduce

  • Try to get the OAuth Proxy running with a local dev environment and a staging environment on a server. - All environments have their own database (nothing shared), different domains.
  • The application is a tanstack-start application.
  • Use drizzleAdapter with provider: "pg"
  • Use advanced.database.generateId: "uuid"
  • Setup the OAuth Proxy
  • Use account.storeStateStrategy === 'cookie' to make the proxy work at all, as without it, the OAuth Proxy plugin still does not use the 'cookie' strategy even if it should do so automatically - but this is a different bug.

The basic configuration of the two environments::

######## Staging build ########

BASE_URL='https://staging.example.dev' # used for `currentURL` parameter of the OAuth Proxy
PRODUCTION_URL='https://staging.example.dev' # used for `productionURL` parameter of the OAuth Proxy
AUTH_TRUSTED_ORIGINS='["https://*.example.dev", "http://localhost:3001"]'
PROJECT_ENV='staging'

AUTH_SECRET='xxxxx' # same on staging + dev
AUTH_DISCORD_ID='xxxxx' # same on staging + dev
AUTH_DISCORD_SECRET='xxxxx' # same on staging + dev

######## Local development server ########

BASE_URL='http://localhost # used for `currentURL` parameter of the OAuth Proxy
PRODUCTION_URL='https://staging.example.dev # used for `productionURL` parameter of the OAuth Proxy
AUTH_TRUSTED_ORIGINS='["http://localhost:3001"]' 
PROJECT_ENV='development'

AUTH_SECRET='xxxxx' # same on staging + dev
AUTH_DISCORD_ID='xxxxx' # same on staging + dev
AUTH_DISCORD_SECRET='xxxxx' # same on staging + dev

Current vs. Expected behavior

After staring the OAuth flow with the development server, logging in into Discord (the OAuth provider in this example) and getting redirected to the staging server, where the OAuth Proxy plugin should kick it and proxy back to the local development server, it errors with the following error:

params: oauth-proxy-XXXXXXXXXX
    at AE.queryWithCache (file:///...22)
    at process.processTicksAndRejections (node:internal/process/task_queues:103:5)
    at async Object.delete (file:///...543)
    at async Object.delete (file:///...8)
    at async s (file:///...02)
    at async Object.deleteVerificationValue (file:///...59)
    at async HI (file:///...75)
    at async file:///...5
    at async s (file:///...47)
    at async file:///...409 {
  query: 'delete from "verification" where "verification"."id" = $1',
  params: [ 'oauth-proxy-XXXXXXXXXX' ],
  cause: hc: invalid input syntax for type uuid: "oauth-proxy-xxxxxxxxxx"
      at $0 (file:///...)
      at Ta (file:///...)
      at Socket.ls (file:///...9)
      at Socket.emit (node:events:508:28)
      at addChunk (node:internal/streams/readable:559:12)
      at readableAddChunkPushByteMode (node:internal/streams/readable:510:3)
      at Readable.push (node:internal/streams/readable:390:5)
      at TCP.onStreamRead (node:internal/stream_base_commons:189:23) {
    severity_local: 'ERROR',
    severity: 'ERROR',
    code: '22P02',
    where: "unnamed portal parameter $1 = '...'",
    file: 'uuid.c',
    line: '174',
    routine: 'string_to_uuid'
  }
}

My guess is, it fails due to the advanced.database.generateId: "uuid" config and the idea to use the "oauth-proxy-xxxxxxxxxx" as an id here in the OAuth Proxy plugin

What version of Better Auth are you using?

1.4.10

System info

{
  "system": {
    "platform": "darwin",
    "arch": "arm64",
    "version": "Darwin Kernel Version 24.6.0: Mon Jul 14 11:30:29 PDT 2025; root:xnu-11417.140.69~1/RELEASE_ARM64_T6000",
    "release": "24.6.0",
    "cpuCount": 10,
    "cpuModel": "Apple M1 Max",
    "totalMemory": "32.00 GB",
    "freeMemory": "0.31 GB"
  },
  "node": {
    "version": "v24.12.0",
    "env": "development"
  },
  "packageManager": {
    "name": "pnpm",
    "version": "10.22.0"
  },
  "frameworks": [
    {
      "name": "react",
      "version": "catalog:react19"
    }
  ],
  "databases": null,
  "betterAuth": {
    "version": "catalog:",
    "config": null
  }

Which area(s) are affected? (Select all that apply)

Package

Auth config (if applicable)

const config = {
  database: drizzleAdapter(db, {
    provider: "pg",
  }),
  baseURL: process.env.PROJECT_ENV === 'staging' ? 'https://staging.example.dev' : 'http://localhost:3001',
  advanced: {
    database: {
      generateId: "uuid",
    },
  },
  account: {
    accountLinking: {
      enabled: true,
    },
    encryptOAuthTokens: false,
    storeStateStrategy: "cookie",
  },
  plugins: [
    oAuthProxy({
      productionURL: 'https://staging.example.dev',
      currentURL: process.env.PROJECT_ENV === 'staging' ? 'https://staging.example.dev' : 'http://localhost:3001',
      maxAge: 60,
    }),
  ],
  socialProviders: {
    discord: {
      clientId: 'XXXX',
      clientSecret: 'XXXX',
      redirectURI: `https://staging.example.dev/api/auth/callback/discord`,
    },
  },
  trustedOrigins: [
    'https://*.example.dev',
    'http://localhost:3001',
  ],
}

Additional context

No response

Originally created by @mimamuh on GitHub (Jan 5, 2026). Original GitHub issue: https://github.com/better-auth/better-auth/issues/7141 Originally assigned to: @bytaesu on GitHub. ### Is this suited for github? - [x] Yes, this is suited for github ### To Reproduce - Try to get the OAuth Proxy running with a **local dev environment** and a **staging environment** on a server. - All environments have their own database (nothing shared), different domains. - The application is a tanstack-start application. - Use `drizzleAdapter` with `provider: "pg"` - Use `advanced.database.generateId: "uuid"` - Setup the OAuth Proxy - Use `account.storeStateStrategy === 'cookie'` to make the proxy work at all, as without it, the OAuth Proxy plugin still does not use the 'cookie' strategy even if it should do so automatically - **but this is a different bug**. The basic configuration of the two environments:: ```sh ######## Staging build ######## BASE_URL='https://staging.example.dev' # used for `currentURL` parameter of the OAuth Proxy PRODUCTION_URL='https://staging.example.dev' # used for `productionURL` parameter of the OAuth Proxy AUTH_TRUSTED_ORIGINS='["https://*.example.dev", "http://localhost:3001"]' PROJECT_ENV='staging' AUTH_SECRET='xxxxx' # same on staging + dev AUTH_DISCORD_ID='xxxxx' # same on staging + dev AUTH_DISCORD_SECRET='xxxxx' # same on staging + dev ######## Local development server ######## BASE_URL='http://localhost # used for `currentURL` parameter of the OAuth Proxy PRODUCTION_URL='https://staging.example.dev # used for `productionURL` parameter of the OAuth Proxy AUTH_TRUSTED_ORIGINS='["http://localhost:3001"]' PROJECT_ENV='development' AUTH_SECRET='xxxxx' # same on staging + dev AUTH_DISCORD_ID='xxxxx' # same on staging + dev AUTH_DISCORD_SECRET='xxxxx' # same on staging + dev ``` ### Current vs. Expected behavior After staring the OAuth flow with the development server, logging in into Discord (the OAuth provider in this example) and getting redirected to the staging server, where the OAuth Proxy plugin should kick it and proxy back to the local development server, it errors with the following error: ``` params: oauth-proxy-XXXXXXXXXX at AE.queryWithCache (file:///...22) at process.processTicksAndRejections (node:internal/process/task_queues:103:5) at async Object.delete (file:///...543) at async Object.delete (file:///...8) at async s (file:///...02) at async Object.deleteVerificationValue (file:///...59) at async HI (file:///...75) at async file:///...5 at async s (file:///...47) at async file:///...409 { query: 'delete from "verification" where "verification"."id" = $1', params: [ 'oauth-proxy-XXXXXXXXXX' ], cause: hc: invalid input syntax for type uuid: "oauth-proxy-xxxxxxxxxx" at $0 (file:///...) at Ta (file:///...) at Socket.ls (file:///...9) at Socket.emit (node:events:508:28) at addChunk (node:internal/streams/readable:559:12) at readableAddChunkPushByteMode (node:internal/streams/readable:510:3) at Readable.push (node:internal/streams/readable:390:5) at TCP.onStreamRead (node:internal/stream_base_commons:189:23) { severity_local: 'ERROR', severity: 'ERROR', code: '22P02', where: "unnamed portal parameter $1 = '...'", file: 'uuid.c', line: '174', routine: 'string_to_uuid' } } ``` My guess is, it fails due to the `advanced.database.generateId: "uuid"` config and the idea to use the `"oauth-proxy-xxxxxxxxxx"` as an id [here in the OAuth Proxy plugin](https://github.com/better-auth/better-auth/blob/e55516b29631af701e196ea3bb86a46aecb62571/packages/better-auth/src/plugins/oauth-proxy/index.ts#L346) ### What version of Better Auth are you using? 1.4.10 ### System info ```bash { "system": { "platform": "darwin", "arch": "arm64", "version": "Darwin Kernel Version 24.6.0: Mon Jul 14 11:30:29 PDT 2025; root:xnu-11417.140.69~1/RELEASE_ARM64_T6000", "release": "24.6.0", "cpuCount": 10, "cpuModel": "Apple M1 Max", "totalMemory": "32.00 GB", "freeMemory": "0.31 GB" }, "node": { "version": "v24.12.0", "env": "development" }, "packageManager": { "name": "pnpm", "version": "10.22.0" }, "frameworks": [ { "name": "react", "version": "catalog:react19" } ], "databases": null, "betterAuth": { "version": "catalog:", "config": null } ``` ### Which area(s) are affected? (Select all that apply) Package ### Auth config (if applicable) ```typescript const config = { database: drizzleAdapter(db, { provider: "pg", }), baseURL: process.env.PROJECT_ENV === 'staging' ? 'https://staging.example.dev' : 'http://localhost:3001', advanced: { database: { generateId: "uuid", }, }, account: { accountLinking: { enabled: true, }, encryptOAuthTokens: false, storeStateStrategy: "cookie", }, plugins: [ oAuthProxy({ productionURL: 'https://staging.example.dev', currentURL: process.env.PROJECT_ENV === 'staging' ? 'https://staging.example.dev' : 'http://localhost:3001', maxAge: 60, }), ], socialProviders: { discord: { clientId: 'XXXX', clientSecret: 'XXXX', redirectURI: `https://staging.example.dev/api/auth/callback/discord`, }, }, trustedOrigins: [ 'https://*.example.dev', 'http://localhost:3001', ], } ``` ### Additional context _No response_
GiteaMirror added the oauthbug labels 2026-04-13 07:04:06 -05:00
Author
Owner

@better-auth-agent[bot] commented on GitHub (Jan 5, 2026):

It seems you're encountering an issue with the OAuth Proxy, specifically related to the deletion of verification entries when using a UUID for the ID, as indicated by the error message: invalid input syntax for type uuid: "oauth-proxy-XXXXXXXXXX". This suggests a mismatch because the ID being used does not conform to the expected UUID format.

To troubleshoot:

  1. Check the ID Generation: Since you're using advanced.database.generateId: "uuid", ensure that any ID generated for verification follows the UUID format. The mention of using "oauth-proxy-XXXXXXXXXX" indicates that you might be passing a string that doesn’t meet this format, leading to the query failure.

  2. Configuration Review: Double-check the configuration for your OAuth Proxy plugin to ensure that all parameters are set correctly, particularly productionURL and currentURL to avoid redirects that may not align with your expected setup.

  3. Debug Logging: Add logging around the flow leading to the deletion of the verification ID to capture what ID is being passed and whether it aligns with your expectations.

There have been related discussions about skipping state checks and proxy configurations that might affect this setup. You may want to reference specific bugs or fixes in Better Auth related to the OAuth Proxy to see if newer changes address any issues stemming from similar configurations [1], [2].

If you continue to face difficulties, consider tagging @bekacru or @ping__ for more specialized insights from the Better Auth team.

Is there a specific part of this flow you’d like further clarification on or additional issues you're facing?

If you need more help, tag @better-auth-agent in a comment so I can respond.

DiagramDiscordGitHub

Diagram Join Star

<!-- gh-comment-id:3712493233 --> @better-auth-agent[bot] commented on GitHub (Jan 5, 2026): It seems you're encountering an issue with the OAuth Proxy, specifically related to the deletion of verification entries when using a UUID for the ID, as indicated by the error message: `invalid input syntax for type uuid: "oauth-proxy-XXXXXXXXXX"`. This suggests a mismatch because the ID being used does not conform to the expected UUID format. To troubleshoot: 1. **Check the ID Generation**: Since you're using `advanced.database.generateId: "uuid"`, ensure that any ID generated for verification follows the UUID format. The mention of using `"oauth-proxy-XXXXXXXXXX"` indicates that you might be passing a string that doesn’t meet this format, leading to the query failure. 2. **Configuration Review**: Double-check the configuration for your OAuth Proxy plugin to ensure that all parameters are set correctly, particularly `productionURL` and `currentURL` to avoid redirects that may not align with your expected setup. 3. **Debug Logging**: Add logging around the flow leading to the deletion of the verification ID to capture what ID is being passed and whether it aligns with your expectations. There have been related discussions about skipping state checks and proxy configurations that might affect this setup. You may want to reference specific bugs or fixes in Better Auth related to the OAuth Proxy to see if newer changes address any issues stemming from similar configurations [[1]](https://github.com/better-auth/better-auth/pull/4991), [[2]](https://www.better-auth.com/docs/plugins/oauth-proxy). If you continue to face difficulties, consider tagging @bekacru or @ping__ for more specialized insights from the Better Auth team. Is there a specific part of this flow you’d like further clarification on or additional issues you're facing? _If you need more help, tag @better-auth-agent in a comment so I can respond._ <!-- bot:webhook reply v1 --> [Diagram](https://repodiagrams.s3.eu-north-1.amazonaws.com/skyvern_ultra_detailed_interactive.html) • [Discord](https://discord.gg/fG2XXEuQX3) • [GitHub](https://github.com/Skyvern-AI/Skyvern) [![Diagram](https://img.shields.io/badge/Diagram-2b3137?style=flat-square)](https://repodiagrams.s3.eu-north-1.amazonaws.com/skyvern_ultra_detailed_interactive.html) [![Join](https://img.shields.io/badge/join-5865F2?logo=discord&logoColor=white&style=flat-square)](https://discord.gg/fG2XXEuQX3) [![Star](https://img.shields.io/badge/star-181717?logo=github&logoColor=white&style=flat-square)](https://github.com/Skyvern-AI/Skyvern)
Author
Owner

@bytaesu commented on GitHub (Jan 6, 2026):

Hi @mimamuh,

All environments have their own database (nothing shared)

It's possible that different environments are pointing to different verification tables. The OAuth Proxy wasn't designed with separate databases per environment in mind, it’s meant as a utility plugin to quickly test logins during development without creating new OAuth clients. I'll take a look into this 🙂

In the meantime, could you check whether it works when both are using the same database?

<!-- gh-comment-id:3713580371 --> @bytaesu commented on GitHub (Jan 6, 2026): Hi @mimamuh, > All environments have their own database (nothing shared) It's possible that different environments are pointing to different verification tables. The OAuth Proxy wasn't designed with separate databases per environment in mind, it’s meant as a utility plugin to quickly test logins during development without creating new OAuth clients. I'll take a look into this 🙂 In the meantime, could you check whether it works when both are using the same database?
Author
Owner

@mimamuh commented on GitHub (Jan 6, 2026):

Hi @bytaesu,

The OAuth Proxy wasn't designed with separate databases per environment in mind

Ah, okay, this would be super valuable to have it as a warning in the docs that this is a requirement, as it took me hours to try to get this thing running.

But this would also meant, that the plugin is useless for me. I start custom preview and dev deployments via CI/CD with their own database and try to use staging just as a OAuth proxy. Have you considered taking the plugin in the direction these guys here have tried with #1819?

In the meantime, could you check whether it works when both are using the same database?
I've checked it by temporarily connecting the local development environment to the staging database, but the same error happens as mentioned with the ticket.

The issue by the error message is, that postgres errors with 22P02, which, by their docs, is INVALID TEXT REPRESENTATION.

code: '22P02',
    where: "unnamed portal parameter $1 = '...'",
    file: 'uuid.c',
    line: '174',
    routine: 'string_to_uuid'

By reading the error message, I strongly assume that the use of the advanced.database.generateId: "uuid" config and the idea to use the "oauth-proxy-xxxxxxxxxx" as an id format here in the OAuth Proxy plugin, fails, as this is not a valid uuid.


FYI: Off-topic to the error of the ticket: At my first tries to get the OAuth plugin up and running, I also did not use account.storeStateStrategy: "cookie" option, as, by reading and analysing the source code, it seemed to me, that this should be automatically handled by the OAuth plugin. But it did not work.

It always failed with the please_restart_the_process error in the url and "State Mismatch" error logged as it was trying to lookup the session in the staging database, but as the request was initiated locally with the local development database. Therefore, the session was not present in the staging database of course – it makes sense now, as you mentioned, it still only works when they share the same database.

I will try the custom plugin solution of @shaug here now – I simply got confused by your update here as I thought you have been aware about the separated databases issue/requirement when you did your OAuth plugin changes.

Again, it would be cool to have the database requirement documented like so – even better, if the plugin would work with isolated databases + different environment URLs:
Image

<!-- gh-comment-id:3714293591 --> @mimamuh commented on GitHub (Jan 6, 2026): Hi @bytaesu, > The OAuth Proxy wasn't designed with separate databases per environment in mind Ah, okay, this would be super valuable to have it as a warning in the docs that this is a requirement, as it took me hours to try to get this thing running. But this would also meant, that the plugin is useless for me. I start custom preview and dev deployments via CI/CD with their own database and try to use staging just as a OAuth proxy. Have you considered taking the plugin in the direction these guys here have tried with #1819? > In the meantime, could you check whether it works when both are using the same database? I've checked it by temporarily connecting the **local development** environment to the **staging database**, but the same error happens as mentioned with the ticket. The issue by the error message is, that postgres errors with `22P02`, which, by their [docs](https://www.postgresql.org/docs/8.2/errcodes-appendix.html), is `INVALID TEXT REPRESENTATION`. ``` code: '22P02', where: "unnamed portal parameter $1 = '...'", file: 'uuid.c', line: '174', routine: 'string_to_uuid' ``` By reading the error message, I strongly assume that the use of the `advanced.database.generateId: "uuid"` config and the idea to use the `"oauth-proxy-xxxxxxxxxx"` as an id format [here in the OAuth Proxy plugin](https://github.com/better-auth/better-auth/blob/e55516b29631af701e196ea3bb86a46aecb62571/packages/better-auth/src/plugins/oauth-proxy/index.ts#L346), fails, as this is not a valid `uuid`. --- FYI: Off-topic to the error of the ticket: At my first tries to get the OAuth plugin up and running, I also did not use `account.storeStateStrategy: "cookie"` option, as, by reading and analysing the source code, it seemed to me, that this should be automatically handled by the OAuth plugin. But it did not work. It always failed with the `please_restart_the_process` error in the url and "State Mismatch" error logged as it was trying to lookup the session in the **staging database**, but as the request was initiated locally with the **local development database**. Therefore, the session was not present in the **staging database** of course – it makes sense now, as you mentioned, it still only works when they share the same database. I will try the custom plugin solution of @shaug [here](https://github.com/better-auth/better-auth/issues/1819#issuecomment-3003038278) now – I simply got confused by your update [here](https://github.com/better-auth/better-auth/issues/1819#issuecomment-3478131893) as I thought you have been aware about the separated databases issue/requirement when you did your OAuth plugin changes. Again, it would be cool to have the database requirement documented like so – even better, if the plugin would work with isolated databases + different environment URLs: <img width="1740" height="424" alt="Image" src="https://github.com/user-attachments/assets/d346ab18-8e76-469c-ba44-5bbc913cf432" />
Author
Owner

@bytaesu commented on GitHub (Jan 7, 2026):

Hi @mimamuh,

v1.4.10, It currently supports both stateless and database modes, and based on my own testing, there don’t seem to be issues. You can check the environment I tested on here: https://github.com/bytaesu/ba-oauth-proxy-example.

If you have any other questions or issues, feel free to let me know 🙏

Note

Please note that the OAuth Proxy interacts with dev/preview and production environments, so it must already be deployed in production.


https://github.com/user-attachments/assets/34950109-630f-481e-98a0-c612cc89c80d

Postgres with UUID

https://github.com/user-attachments/assets/27303e8a-dd8f-4952-9d68-03d0e7c300ee

<!-- gh-comment-id:3717417810 --> @bytaesu commented on GitHub (Jan 7, 2026): Hi @mimamuh, `v1.4.10`, It currently supports both stateless and database modes, and based on my own testing, there don’t seem to be issues. You can check the environment I tested on here: https://github.com/bytaesu/ba-oauth-proxy-example. If you have any other questions or issues, feel free to let me know 🙏 > [!NOTE] > Please note that the OAuth Proxy interacts with dev/preview and production environments, so it must already be deployed in production. --- ### Stateless strategy (cookie-based) https://github.com/user-attachments/assets/34950109-630f-481e-98a0-c612cc89c80d ### Postgres with UUID https://github.com/user-attachments/assets/27303e8a-dd8f-4952-9d68-03d0e7c300ee
Author
Owner

@cflee commented on GitHub (Jan 14, 2026):

Again, it would be cool to have the database requirement documented like so

+1 to this – I just ran into this issue trying to get the database mode to work, as the shared database (and shared secret) requirement is not documented for this plugin at all. I'm migrating from Auth.js where the equivalent functionality of OAuth Proxy does not have this shared database requirement.

<!-- gh-comment-id:3748012241 --> @cflee commented on GitHub (Jan 14, 2026): > Again, it would be cool to have the database requirement documented like so +1 to this – I just ran into this issue trying to get the database mode to work, as the shared database (and shared secret) requirement is not documented for this plugin at all. I'm migrating from Auth.js where the equivalent functionality of OAuth Proxy does not have this shared database requirement.
Author
Owner

@bytaesu commented on GitHub (Jan 15, 2026):

+1 to this – I just ran into this issue trying to get the database mode to work, as the shared database (and shared secret) requirement is not documented for this plugin at all. I'm migrating from Auth.js where the equivalent functionality of OAuth Proxy does not have this shared database requirement.

Hello @cflee,

Could you share reference links for the OAuth Proxy you've been using? I'll try to improve OAuth Proxy Plugin to support it 🫡

<!-- gh-comment-id:3752587425 --> @bytaesu commented on GitHub (Jan 15, 2026): > +1 to this – I just ran into this issue trying to get the database mode to work, as the shared database (and shared secret) requirement is not documented for this plugin at all. I'm migrating from Auth.js where the equivalent functionality of OAuth Proxy does not have this shared database requirement. Hello @cflee, Could you share reference links for the OAuth Proxy you've been using? I'll try to improve OAuth Proxy Plugin to support it 🫡
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#10745