Skip to content

fix: ensure UTC session timezone in PrismaPg connections (#4285)#4321

Open
sudoeren wants to merge 2 commits into
umami-software:devfrom
sudoeren:fix/4285-timestamp-timezone
Open

fix: ensure UTC session timezone in PrismaPg connections (#4285)#4321
sudoeren wants to merge 2 commits into
umami-software:devfrom
sudoeren:fix/4285-timestamp-timezone

Conversation

@sudoeren

@sudoeren sudoeren commented Jun 4, 2026

Copy link
Copy Markdown

Summary

Fixes #4285

Root Cause

@prisma/adapter-pg's internal ormatDateTime function converts JavaScript Date objects to PostgreSQL TIMESTAMPTZ strings without appending a timezone offset. For example:

2024-01-15 10:30:00 ← no UTC offset

When the PostgreSQL session timezone is not UTC (e.g. UTC+8), the database interprets the timezone-naive string as being in the session timezone rather than UTC. This causes the stored timestamp to be shifted backward by the timezone offset.

Fix

Append options=-c timezone=UTC to the PostgreSQL connection URL in all three places that create a PrismaPg adapter:

  • src/lib/prisma.ts — main and replica connections
  • scripts/check-db.js
  • scripts/seed/index.ts

This tells PostgreSQL to set the session timezone to UTC for every connection, ensuring timezone-naive TIMESTAMPTZ strings from the adapter are correctly interpreted as UTC.

Closes #4285


View with Codesmith Autofix with Codesmith
Need help on this PR? Tag /codesmith with what you need. Autofix is disabled.

)

@prisma/adapter-pg's internal formatDateTime function converts JS Date
objects to PostgreSQL TIMESTAMPTZ strings without appending a timezone
offset. When the database session timezone is not UTC (e.g. UTC+8),
PostgreSQL misinterprets the value, causing stored timestamps to be
shifted backward.

Fix by appending 'options=-c timezone=UTC' to the connection URL in all
three places that create a PrismaPg adapter, ensuring every session
interprets timezone-naive timestamp strings as UTC.
@vercel

vercel Bot commented Jun 4, 2026

Copy link
Copy Markdown

@sudoeren is attempting to deploy a commit to the Umami Software Team on Vercel.

A member of the Team first needs to authorize it.

@greptile-apps

greptile-apps Bot commented Jun 4, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes a session-timezone mismatch in @prisma/adapter-pg connections by appending options=-c timezone=UTC to every PostgreSQL connection URL before constructing a PrismaPg adapter. The fix is applied consistently across the main/replica client in src/lib/prisma.ts, the startup health-check script, and the seed script.

  • src/lib/prisma.ts / scripts/check-db.js: The URL-patching logic is correct and handles pre-existing options gracefully; the includes('timezone') guard has a minor false-positive risk (e.g. log_timezone) that could silently leave the session timezone unset for edge-case connection strings.
  • scripts/seed/index.ts: The new code references connectionUrl after its try block — const connectionUrl is block-scoped to that block, so the variable is out of scope at the point of use, causing a TypeScript compile error and a ReferenceError at runtime. The seed script cannot run in its current form.

Confidence Score: 3/5

Not safe to merge as-is: the seed script will fail to compile and crash at runtime due to a variable scoping mistake.

The core fix in src/lib/prisma.ts and scripts/check-db.js is sound, but scripts/seed/index.ts introduces a block-scoping mistake that makes the variable connectionUrl inaccessible after the try block ends. TypeScript will reject the file at compile time, and any attempt to run the seed script will throw a ReferenceError. The other two files work correctly and would be safe to ship independently.

scripts/seed/index.ts — the connectionUrl variable must be declared with let outside the try block and assigned inside it, then used after.

Important Files Changed

Filename Overview
scripts/seed/index.ts Timezone fix references connectionUrl outside its try block scope — TypeScript compile error and runtime ReferenceError; seed script is broken by this change.
src/lib/prisma.ts Correctly appends -c timezone=UTC to both the primary and replica connection URLs; includes('timezone') guard has a minor false-positive risk with log_timezone.
scripts/check-db.js Cleanly applies the same timezone URL patching pattern; same substring-check caveat as the other files but no scoping issue.

Sequence Diagram

sequenceDiagram
    participant App
    participant getClient
    participant URL as URL Parser
    participant PrismaPg
    participant PG as PostgreSQL

    App->>getClient: initialize client
    getClient->>URL: new URL(DATABASE_URL)
    URL-->>getClient: connectionUrl
    getClient->>getClient: check existingOptions for 'timezone'
    alt timezone not set
        getClient->>connectionUrl: "set options=-c timezone=UTC"
    end
    getClient->>PrismaPg: "new PrismaPg({ connectionString })"
    PrismaPg->>PG: "connect with options=-c timezone=UTC"
    PG-->>PrismaPg: "session timezone = UTC"
    PrismaPg-->>getClient: adapter ready
    getClient->>App: PrismaClient with UTC session
Loading

Comments Outside Diff (1)

  1. scripts/seed/index.ts, line 282-302 (link)

    P1 connectionUrl is declared with const inside the try block (line 284) and is therefore block-scoped to that block. Accessing it at lines 294–302 is outside that scope, which causes a TypeScript compile error (Cannot find name 'connectionUrl') and a ReferenceError at runtime — meaning the seed script cannot run at all with this change.

Reviews (1): Last reviewed commit: "Ensure UTC session timezone in PrismaPg ..." | Re-trigger Greptile

Comment thread src/lib/prisma.ts Outdated
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
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