@better-auth/api-key generates MySQL-syntax migrations when using PostgreSQL #3025

Closed
opened 2026-03-13 10:35:05 -05:00 by GiteaMirror · 0 comments
Owner

Originally created by @simon-dk on GitHub (Mar 10, 2026).

Is this suited for github?

  • Yes, this is suited for github

To Reproduce

  1. Set up better-auth with PostgreSQL and the @better-auth/api-key plugin
  2. Run npx auth generate
  3. Observe the generated SQL

Current vs. Expected behavior

Generated SQL (incorrect)

alter table "apikey" add index "apikey_configId_idx";
alter table "apikey" add column "configId" text not null;
alter table "apikey" add index "apikey_referenceId_idx";
alter table "apikey" add column "referenceId" text not null;

ADD INDEX is MySQL syntax and is not valid PostgreSQL. PostgreSQL error code: 42704 (typenameType).

Expected SQL

ALTER TABLE "apikey" ADD COLUMN IF NOT EXISTS "configId" text NOT NULL DEFAULT 'default';
ALTER TABLE "apikey" RENAME COLUMN "userId" TO "referenceId";
CREATE INDEX IF NOT EXISTS "apikey_configId_idx" ON "apikey" ("configId");
CREATE INDEX IF NOT EXISTS "apikey_referenceId_idx" ON "apikey" ("referenceId");

What version of Better Auth are you using?

1.5.4

System info

{
  "system": {
    "platform": "darwin",
    "arch": "arm64",
    "version": "Darwin Kernel Version 25.3.0: Wed Jan 28 20:53:31 PST 2026; root:xnu-12377.91.3~2/RELEASE_ARM64_T8103",
    "release": "25.3.0",
    "cpuCount": 8,
    "cpuModel": "Apple M1",
    "totalMemory": "16.00 GB",
    "freeMemory": "0.15 GB"
  },
  "node": {
    "version": "v22.13.0",
    "env": "development"
  },
  "packageManager": {
    "name": "npm",
    "version": "11.3.0"
  },
  "frameworks": [
    {
      "name": "next",
      "version": "16.1.6"
    },
    {
      "name": "react",
      "version": "19.2.4"
    }
  ],
  "databases": [
    {
      "name": "pg",
      "version": "^8.20.0"
    }
  ],
  "betterAuth": {
    "version": "^1.5.4",
    "config": {
      "secret": "[REDACTED]",
      "database": {
        "_events": {},
        "_eventsCount": 0,
        "options": {
          "connectionString": "[REDACTED]",
          "max": 10,
          "min": 0,
          "maxUses": null,
          "allowExitOnIdle": false,
          "maxLifetimeSeconds": 0,
          "idleTimeoutMillis": 10000
        },
        "_clients": [],
        "_idle": [],
        "_expired": {},
        "_pendingQueue": [],
        "ending": false,
        "ended": false
      },
      "plugins": [
        {
          "name": "api-key",
          "config": {
            "id": "api-key",
            "$ERROR_CODES": "<REMOVED FOR BREVITY>",
            "hooks": {
              "before": [
                {}
              ]
            },
            "endpoints": {},
            "schema": {
              "apikey": {
                "fields": {
                  "configId": {
                    "type": "string",
                    "required": true,
                    "defaultValue": "default",
                    "input": false,
                    "index": true
                  },
                  "name": {
                    "type": "string",
                    "required": false,
                    "input": false
                  },
                  "start": {
                    "type": "string",
                    "required": false,
                    "input": false
                  },
                  "referenceId": {
                    "type": "string",
                    "required": true,
                    "input": false,
                    "index": true
                  },
                  "prefix": {
                    "type": "string",
                    "required": false,
                    "input": false
                  },
                  "key": {
                    "type": "string",
                    "required": true,
                    "input": false,
                    "index": true
                  },
                  "refillInterval": {
                    "type": "number",
                    "required": false,
                    "input": false
                  },
                  "refillAmount": {
                    "type": "number",
                    "required": false,
                    "input": false
                  },
                  "lastRefillAt": {
                    "type": "date",
                    "required": false,
                    "input": false
                  },
                  "enabled": {
                    "type": "boolean",
                    "required": false,
                    "input": false,
                    "defaultValue": true
                  },
                  "rateLimitEnabled": {
                    "type": "boolean",
                    "required": false,
                    "input": false,
                    "defaultValue": true
                  },
                  "rateLimitTimeWindow": {
                    "type": "number",
                    "required": false,
                    "input": false,
                    "defaultValue": 86400000
                  },
                  "rateLimitMax": {
                    "type": "number",
                    "required": false,
                    "input": false,
                    "defaultValue": 10
                  },
                  "requestCount": {
                    "type": "number",
                    "required": false,
                    "input": false,
                    "defaultValue": 0
                  },
                  "remaining": {
                    "type": "number",
                    "required": false,
                    "input": false
                  },
                  "lastRequest": {
                    "type": "date",
                    "required": false,
                    "input": false
                  },
                  "expiresAt": {
                    "type": "date",
                    "required": false,
                    "input": false
                  },
                  "createdAt": {
                    "type": "date",
                    "required": true,
                    "input": false
                  },
                  "updatedAt": {
                    "type": "date",
                    "required": true,
                    "input": false
                  },
                  "permissions": {
                    "type": "string",
                    "required": false,
                    "input": false
                  },
                  "metadata": {
                    "type": "string",
                    "required": false,
                    "input": true,
                    "transform": {}
                  }
                }
              }
            },
            "configurations": [
              {
                "enableMetadata": true,
                "apiKeyHeaders": "x-api-key",
                "defaultKeyLength": 64,
                "maximumPrefixLength": 32,
                "minimumPrefixLength": 1,
                "maximumNameLength": 32,
                "minimumNameLength": 1,
                "disableKeyHashing": false,
                "requireName": false,
                "storage": "database",
                "rateLimit": {
                  "enabled": true,
                  "timeWindow": 86400000,
                  "maxRequests": 10
                },
                "keyExpiration": {
                  "defaultExpiresIn": null,
                  "disableCustomExpiresTime": false,
                  "maxExpiresIn": 365,
                  "minExpiresIn": 1
                },
                "startingCharactersConfig": {
                  "shouldStore": true,
                  "charactersLength": 6
                },
                "enableSessionForAPIKeys": false,
                "fallbackToDatabase": false,
                "deferUpdates": false
              }
            ]
          }
        }
    
      ]
    }
  }
}

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

Backend

Additional context

This appears to affect the new configId and referenceId columns introduced in 1.5.0. The npx auth migrate command fails entirely, leaving the database unchanged, so there is no partial state to worry about. We migrated from 1.4.17, updated all packages/imports and ran npx auth generate.

Originally created by @simon-dk on GitHub (Mar 10, 2026). ### Is this suited for github? - [x] Yes, this is suited for github ### To Reproduce 1. Set up better-auth with PostgreSQL and the @better-auth/api-key plugin 2. Run npx auth generate 3. Observe the generated SQL ### Current vs. Expected behavior Generated SQL (incorrect) alter table "apikey" add index "apikey_configId_idx"; alter table "apikey" add column "configId" text not null; alter table "apikey" add index "apikey_referenceId_idx"; alter table "apikey" add column "referenceId" text not null; ADD INDEX is MySQL syntax and is not valid PostgreSQL. PostgreSQL error code: 42704 (typenameType). Expected SQL ALTER TABLE "apikey" ADD COLUMN IF NOT EXISTS "configId" text NOT NULL DEFAULT 'default'; ALTER TABLE "apikey" RENAME COLUMN "userId" TO "referenceId"; CREATE INDEX IF NOT EXISTS "apikey_configId_idx" ON "apikey" ("configId"); CREATE INDEX IF NOT EXISTS "apikey_referenceId_idx" ON "apikey" ("referenceId"); ### What version of Better Auth are you using? 1.5.4 ### System info ```bash { "system": { "platform": "darwin", "arch": "arm64", "version": "Darwin Kernel Version 25.3.0: Wed Jan 28 20:53:31 PST 2026; root:xnu-12377.91.3~2/RELEASE_ARM64_T8103", "release": "25.3.0", "cpuCount": 8, "cpuModel": "Apple M1", "totalMemory": "16.00 GB", "freeMemory": "0.15 GB" }, "node": { "version": "v22.13.0", "env": "development" }, "packageManager": { "name": "npm", "version": "11.3.0" }, "frameworks": [ { "name": "next", "version": "16.1.6" }, { "name": "react", "version": "19.2.4" } ], "databases": [ { "name": "pg", "version": "^8.20.0" } ], "betterAuth": { "version": "^1.5.4", "config": { "secret": "[REDACTED]", "database": { "_events": {}, "_eventsCount": 0, "options": { "connectionString": "[REDACTED]", "max": 10, "min": 0, "maxUses": null, "allowExitOnIdle": false, "maxLifetimeSeconds": 0, "idleTimeoutMillis": 10000 }, "_clients": [], "_idle": [], "_expired": {}, "_pendingQueue": [], "ending": false, "ended": false }, "plugins": [ { "name": "api-key", "config": { "id": "api-key", "$ERROR_CODES": "<REMOVED FOR BREVITY>", "hooks": { "before": [ {} ] }, "endpoints": {}, "schema": { "apikey": { "fields": { "configId": { "type": "string", "required": true, "defaultValue": "default", "input": false, "index": true }, "name": { "type": "string", "required": false, "input": false }, "start": { "type": "string", "required": false, "input": false }, "referenceId": { "type": "string", "required": true, "input": false, "index": true }, "prefix": { "type": "string", "required": false, "input": false }, "key": { "type": "string", "required": true, "input": false, "index": true }, "refillInterval": { "type": "number", "required": false, "input": false }, "refillAmount": { "type": "number", "required": false, "input": false }, "lastRefillAt": { "type": "date", "required": false, "input": false }, "enabled": { "type": "boolean", "required": false, "input": false, "defaultValue": true }, "rateLimitEnabled": { "type": "boolean", "required": false, "input": false, "defaultValue": true }, "rateLimitTimeWindow": { "type": "number", "required": false, "input": false, "defaultValue": 86400000 }, "rateLimitMax": { "type": "number", "required": false, "input": false, "defaultValue": 10 }, "requestCount": { "type": "number", "required": false, "input": false, "defaultValue": 0 }, "remaining": { "type": "number", "required": false, "input": false }, "lastRequest": { "type": "date", "required": false, "input": false }, "expiresAt": { "type": "date", "required": false, "input": false }, "createdAt": { "type": "date", "required": true, "input": false }, "updatedAt": { "type": "date", "required": true, "input": false }, "permissions": { "type": "string", "required": false, "input": false }, "metadata": { "type": "string", "required": false, "input": true, "transform": {} } } } }, "configurations": [ { "enableMetadata": true, "apiKeyHeaders": "x-api-key", "defaultKeyLength": 64, "maximumPrefixLength": 32, "minimumPrefixLength": 1, "maximumNameLength": 32, "minimumNameLength": 1, "disableKeyHashing": false, "requireName": false, "storage": "database", "rateLimit": { "enabled": true, "timeWindow": 86400000, "maxRequests": 10 }, "keyExpiration": { "defaultExpiresIn": null, "disableCustomExpiresTime": false, "maxExpiresIn": 365, "minExpiresIn": 1 }, "startingCharactersConfig": { "shouldStore": true, "charactersLength": 6 }, "enableSessionForAPIKeys": false, "fallbackToDatabase": false, "deferUpdates": false } ] } } ] } } } ``` ### Which area(s) are affected? (Select all that apply) Backend ### Additional context This appears to affect the new configId and referenceId columns introduced in 1.5.0. The npx auth migrate command fails entirely, leaving the database unchanged, so there is no partial state to worry about. We migrated from 1.4.17, updated all packages/imports and ran npx auth generate.
GiteaMirror added the bug label 2026-03-13 10:35:05 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#3025