Bug Fixes
atprotoState.expiresAtnow stored as adateinstead of a raw epoch-millisecond number. This aligns with better-auth's own idiomatic handling of ephemeral tokens (e.g.verification.expiresAt) and maps to proper timestamp columns across dialects (SQLitedate, Postgrestimestamptz, MySQLtimestamp(3)). The state store now normalizes bothDateand legacynumbervalues when reading.atprotoSession.userIdis now nullable. During the OAuth flow a temporary session row is created before the user is identified. Previously this inserted an empty-stringuserId, which violated theNOT NULL+ foreign-key constraint on Postgres and surfaced asCALLBACK_FAILED. The temp row now insertsnulland is back-filled with the realuserIdin the callback handler once the user is resolved.
Maintenance
- Bumped
hono(devDependency, used only in the demo) to4.13.2, resolving 6 Dependabot advisories. - Bumped SHA-pinned GitHub Actions:
actions/checkoutv7.0.1,actions/setup-nodev7.0.0.
Migration
Fresh installs need nothing — the schema is generated correctly.
Existing deployments require a one-time manual migration. better-auth's auto-migration only adds missing tables/columns; it does not alter the type or nullability of existing columns (it only logs a warning). Run the following once against your database.
atprotoState is ephemeral (~10 min TTL), so dropping its rows is safe.
PostgreSQL
DELETE FROM "atprotoState";
ALTER TABLE "atprotoState"
ALTER COLUMN "expiresAt" TYPE timestamptz USING to_timestamp("expiresAt" / 1000.0);
ALTER TABLE "atprotoSession"
ALTER COLUMN "userId" DROP NOT NULL;MySQL
DELETE FROM `atprotoState`;
ALTER TABLE `atprotoState`
MODIFY COLUMN `expiresAt` TIMESTAMP(3) NULL;
ALTER TABLE `atprotoSession`
MODIFY COLUMN `userId` VARCHAR(255) NULL;SQLite
SQLite stores dates as timestamps and does not enforce a separate column type here, so only the nullability of userId matters. If your adapter created userId as NOT NULL, recreate the table (SQLite cannot drop a NOT NULL constraint via ALTER):
DELETE FROM "atprotoState";
-- Recreate atprotoSession with a nullable userId if it was NOT NULL.
-- Adjust column list to match your generated schema before running.Full Changelog: v0.2.0...v0.3.0