Skip to content

Bug: PgAdapter corrupts historical dates with 2-digit years (00-99 AD) #28192

@kboshold

Description

@kboshold

Bug description

When using @prisma/adapter-pg, historical dates with 2-digit years are incorrectly interpreted, causing data corruption and runtime errors.

Affected years:

  • Years 31: Throws RangeError: Invalid time value
  • Years 32-49: Incorrectly converted to 20xx (e.g., 32 AD → 2032 AD)
  • Years 50-99: Incorrectly converted to 19xx (e.g., 50 AD → 1950 AD)
  • Years 100+: Work correctly

Important: This bug only affects PgAdapter. Traditional Prisma connections handle these dates correctly.

Reproduction:
Repository with complete Docker setup: kboshold/bug-reproduction-prisma-date

Run with: docker compose up

Test output:

🔍 Prisma Date Bug Reproduction Test

Testing with PgAdapter



Testing 0031-01-01:
 ❌ CREATE 0031-01-01T00:00:00.000Z => Error: RangeError: Invalid time value
 ❌ UPDATE 0031-01-01T00:00:00.000Z => Error: RangeError: Invalid time value

Testing 0032-01-01:
 ❌ CREATE 0032-01-01T00:00:00.000Z => 2032-01-01T00:00:00.000Z (32 -> 2032)
 ❌ UPDATE 0032-01-01T00:00:00.000Z => 2032-01-01T00:00:00.000Z (32 -> 2032)

Testing 0040-01-01:
 ❌ CREATE 0040-01-01T00:00:00.000Z => 2040-01-01T00:00:00.000Z (40 -> 2040)
 ❌ UPDATE 0040-01-01T00:00:00.000Z => 2040-01-01T00:00:00.000Z (40 -> 2040)

Testing 0050-01-01:
 ❌ CREATE 0050-01-01T00:00:00.000Z => 1950-01-01T00:00:00.000Z (50 -> 1950)
 ❌ UPDATE 0050-01-01T00:00:00.000Z => 1950-01-01T00:00:00.000Z (50 -> 1950)

Testing 0120-01-01:
 ✅ CREATE 0120-01-01T00:00:00.000Z => 0120-01-01T00:00:00.000Z (120 -> 120)
 ✅ UPDATE 0120-01-01T00:00:00.000Z => 0120-01-01T00:00:00.000Z (120 -> 120)

Testing with Traditional Connection

Testing 0031-01-01:
 ✅ CREATE 0031-01-01T00:00:00.000Z => 0031-01-01T00:00:00.000Z (31 -> 31)
 ✅ UPDATE 0031-01-01T00:00:00.000Z => 0031-01-01T00:00:00.000Z (31 -> 31)

Testing 0032-01-01:
 ✅ CREATE 0032-01-01T00:00:00.000Z => 0032-01-01T00:00:00.000Z (32 -> 32)
 ✅ UPDATE 0032-01-01T00:00:00.000Z => 0032-01-01T00:00:00.000Z (32 -> 32)

Testing 0040-01-01:
 ✅ CREATE 0040-01-01T00:00:00.000Z => 0040-01-01T00:00:00.000Z (40 -> 40)
 ✅ UPDATE 0040-01-01T00:00:00.000Z => 0040-01-01T00:00:00.000Z (40 -> 40)

Testing 0050-01-01:
 ✅ CREATE 0050-01-01T00:00:00.000Z => 0050-01-01T00:00:00.000Z (50 -> 50)
 ✅ UPDATE 0050-01-01T00:00:00.000Z => 0050-01-01T00:00:00.000Z (50 -> 50)

Testing 0120-01-01:
 ✅ CREATE 0120-01-01T00:00:00.000Z => 0120-01-01T00:00:00.000Z (120 -> 120)
 ✅ UPDATE 0120-01-01T00:00:00.000Z => 0120-01-01T00:00:00.000Z (120 -> 120)

Environment:

  • Prisma: 6.16.2
  • @prisma/adapter-pg: 6.16.2
  • Node.js: 24
  • PostgreSQL: 17

Impact:
This affects applications dealing with historical data, genealogy, archaeology, or legacy system migrations. The silent data corruption is particularly dangerous as it may go unnoticed.

Severity

🚨 Critical: Data loss, app crash, security issue

Reproduction

See kboshold/bug-reproduction-prisma-date

Expected vs. Actual Behavior

Current behaviour:

Testing 0031-01-01:
 ❌ CREATE 0031-01-01T00:00:00.000Z => Error: RangeError: Invalid time value
 ❌ UPDATE 0031-01-01T00:00:00.000Z => Error: RangeError: Invalid time value

Testing 0032-01-01:
 ❌ CREATE 0032-01-01T00:00:00.000Z => 2032-01-01T00:00:00.000Z (32 -> 2032)
 ❌ UPDATE 0032-01-01T00:00:00.000Z => 2032-01-01T00:00:00.000Z (32 -> 2032)

Testing 0040-01-01:
 ❌ CREATE 0040-01-01T00:00:00.000Z => 2040-01-01T00:00:00.000Z (40 -> 2040)
 ❌ UPDATE 0040-01-01T00:00:00.000Z => 2040-01-01T00:00:00.000Z (40 -> 2040)

Testing 0050-01-01:
 ❌ CREATE 0050-01-01T00:00:00.000Z => 1950-01-01T00:00:00.000Z (50 -> 1950)
 ❌ UPDATE 0050-01-01T00:00:00.000Z => 1950-01-01T00:00:00.000Z (50 -> 1950)

Testing 0120-01-01:
 ✅ CREATE 0120-01-01T00:00:00.000Z => 0120-01-01T00:00:00.000Z (120 -> 120)
 ✅ UPDATE 0120-01-01T00:00:00.000Z => 0120-01-01T00:00:00.000Z (120 -> 120)

Expected behaviour:

Testing 0031-01-01:
✅ CREATE 0031-01-01T00:00:00.000Z => 0031-01-01T00:00:00.000Z (31 -> 31)
✅ UPDATE 0031-01-01T00:00:00.000Z => 0031-01-01T00:00:00.000Z (31 -> 31)

Testing 0032-01-01:
✅ CREATE 0032-01-01T00:00:00.000Z => 0032-01-01T00:00:00.000Z (32 -> 32)
✅ UPDATE 0032-01-01T00:00:00.000Z => 0032-01-01T00:00:00.000Z (32 -> 32)

Testing 0040-01-01:
✅ CREATE 0040-01-01T00:00:00.000Z => 0040-01-01T00:00:00.000Z (40 -> 40)
✅ UPDATE 0040-01-01T00:00:00.000Z => 0040-01-01T00:00:00.000Z (40 -> 40)

Testing 0050-01-01:
✅ CREATE 0050-01-01T00:00:00.000Z => 0050-01-01T00:00:00.000Z (50 -> 50)
✅ UPDATE 0050-01-01T00:00:00.000Z => 0050-01-01T00:00:00.000Z (50 -> 50)

Testing 0120-01-01:
✅ CREATE 0120-01-01T00:00:00.000Z => 0120-01-01T00:00:00.000Z (120 -> 120)
✅ UPDATE 0120-01-01T00:00:00.000Z => 0120-01-01T00:00:00.000Z (120 -> 120)

Frequency

Consistently reproducible

Does this occur in development or production?

Both development and production

Is this a regression?

  • It does work without PgAdapter.

Workaround

  • Remove PgAdapter.

Prisma Schema & Queries

See kboshold/bug-reproduction-prisma-date

generator client {
  provider   = "prisma-client"
  output     = "./prisma/client"
  engineType = "library"
}

datasource db {
  provider  = "postgres"
  url       = env("DATABASE_URL")
  directUrl = env("DIRECT_DATABASE_URL")
}

model TestData {
  id   String    @id @default(uuid())
  date DateTime?
}
const adapter = new PrismaPg({ connectionString })
const prisma = new PrismaClient({ adapter })

// Throws an error:
const record = await prisma.testData.create({
  data: { date: new Date('0031-01-01T00:00:00.000Z') }
})

Prisma Config

Does not exist.

Logs & Debug Info

// Debug logs here

Environment & Setup

  • OS: Docker / Linux
  • PostgreSQL: 17|
  • Node.js: 24

Prisma Version

- Prisma: 6.16.2
- @prisma/adapter-pg: 6.16.2

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions