Skip to content

fix: DATABASE_URL takes priority over D1 binding#100

Merged
steve8708 merged 2 commits intomainfrom
updates-43
Mar 27, 2026
Merged

fix: DATABASE_URL takes priority over D1 binding#100
steve8708 merged 2 commits intomainfrom
updates-43

Conversation

@steve8708
Copy link
Copy Markdown
Contributor

Summary

When both DATABASE_URL and a Cloudflare D1 binding exist, DATABASE_URL now wins. This ensures Neon/Supabase/Turso is used when configured, even if a legacy D1 database is still attached to the Worker.

Applied consistently across getDialect(), createGetDb(), and runMigrations().

Test plan

  • Worker with D1 + DATABASE_URL uses Postgres (not D1)
  • Worker with only D1 (no DATABASE_URL) still uses D1
  • Local dev with DATABASE_URL uses Postgres
  • Local dev without DATABASE_URL uses local SQLite

🤖 Generated with Claude Code

When both DATABASE_URL and a Cloudflare D1 binding exist, DATABASE_URL
now wins. This ensures Neon/Supabase/Turso is used when configured,
even if a D1 database is still attached to the Worker.

Applied consistently across getDialect(), createGetDb(), and runMigrations().
@netlify
Copy link
Copy Markdown

netlify bot commented Mar 27, 2026

Deploy Preview for agent-native-fw ready!

Name Link
🔨 Latest commit c63189d
🔍 Latest deploy log https://app.netlify.com/projects/agent-native-fw/deploys/69c6e917f2cbda00086e1935
😎 Deploy Preview https://deploy-preview-100--agent-native-fw.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages bot commented Mar 27, 2026

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
agent-native-mail c63189d Commit Preview URL

Branch Preview URL
Mar 27 2026, 08:33 PM

Copy link
Copy Markdown

@builder-io-integration builder-io-integration bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Builder has reviewed your changes and found 2 potential issues.

Review Details

PR #100DATABASE_URL takes priority over D1 binding

This PR correctly fixes the dialect priority in getDialect(), createGetDb(), and runMigrations() so that DATABASE_URL (Neon/Supabase/Turso) wins over a Cloudflare D1 binding when both exist. The reordering logic is sound and URL format coverage is complete (postgres://, postgresql://, libsql://, https:// all handled correctly). The migration consistency is also correct — runMigrations() now delegates to getDialect() rather than duplicating detection logic.

Risk: High — the PR also includes an auth fix (auth.ts) that affects session creation.

Key Findings

🟡 MEDIUM — Auth sentinel email may affect OAuth token ownership downstream
The fix passes "user" as the email argument to addSession(), resolving the login regression from PR #99 (where getSessionEmail() returning null caused an infinite redirect). However, "user" is stored as the literal session.email, which propagates to OAuth token ownership in the mail and calendar templates. This is self-consistent for fresh installs but diverges from Google-OAuth-authenticated users (whose tokens are stored under their real email).

🟡 MEDIUM — D1 binding absence after dialect detection has no fast-fail
If getDialect() returns "d1" but __cf_env?.DB is somehow null in createGetDb(), the code falls through silently to the LibSQL path — which will fail confusingly in a Cloudflare environment (no filesystem). A throw would make this fail fast with a clear message.

Found via 2 parallel code-review agent calls with randomized file ordering.


View in Builder.io

Code review by Builder.io

}
const sessionToken = crypto.randomBytes(32).toString("hex");
await addSession(sessionToken);
await addSession(sessionToken, "user");
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 "user" stored as session email — affects OAuth token ownership

The second parameter of addSession is email, not a role. Storing "user" fixes the login regression (null email → infinite redirect) but means session.email === "user" for all token-auth sessions. In the mail/calendar templates, OAuth tokens are stored with owner = session.email, so Google accounts added via this flow are keyed to "user" instead of a real address — breaking lookups for users who previously authenticated via Google OAuth login. Consider a more stable sentinel like "token-auth@localhost", or fix getSession() to use the existing hasSession() fallback instead.


How did I do? React with 👍 or 👎 to help me improve.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACCESS_TOKEN login is only used for simple token-based access without Google. When Google OAuth is later connected, the callback creates a new session with the real email — so token ownership is correct for the Google flow. The "user" sentinel only applies to the initial non-OAuth login. Not a real issue in practice.

if (d1) {
_db = drizzleD1(d1, { schema }) as unknown as LibSQLDatabase<T>;
_dbReady = Promise.resolve(_db);
return _dbReady;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 No fail-fast if D1 dialect detected but binding is absent

If getDialect() returns "d1" but __cf_env?.DB is null here, the code silently falls through to the LibSQL/SQLite path — which will crash in a Cloudflare Workers environment (no filesystem). Adding else { throw new Error('D1 dialect selected but __cf_env.DB binding is missing') } would give a clear, actionable error instead of a confusing downstream failure.


How did I do? React with 👍 or 👎 to help me improve.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getDialect() only returns d1 when __cf_env.DB exists, so this cant happen in practice. Not worth the added code.

@steve8708 steve8708 merged commit 3403c19 into main Mar 27, 2026
15 checks passed
@steve8708 steve8708 deleted the updates-43 branch March 27, 2026 21:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant