Skip to content

fix(local): pin and own the @prisma/dev the local Postgres emulator runs on - #298

Merged
wmadden-electric merged 3 commits into
mainfrom
claude/postgres-64kib-crash-d04bff
Sep 18, 2026
Merged

wmadden-electric merged 3 commits into
mainfrom
claude/postgres-64kib-crash-d04bff

Conversation

@wmadden-electric

Copy link
Copy Markdown
Contributor

Problem

prisma dev crashed the local Postgres emulator on any message over 64 KiB (Connection terminated unexpectedly, then every later connection refused). The migration runner writes each contract snapshot as one jsonb bind parameter, so any app whose snapshot passes 64 KiB could no longer migrate locally (prisma/asks hit it at its second migration).

The defect is in @electric-sql/pglite-socket 0.0.20, which @prisma/dev 0.20.0 depends on; every @prisma/dev from 0.21.0 has the fix. Composer's published package never declared @prisma/dev and resolved it from the application, so apps got whatever copy alchemy's ^0.20.0 range pulled in (or none at all under pnpm's isolated linker).

Change

  • @prisma/composer-prisma-cloud and @internal/local-target declare @prisma/dev ^0.25.2 as a runtime dependency.
  • The local target resolves @prisma/dev from Composer's own package only. The application fallback is removed: Composer owns the emulator version, and an app's transitive copy must not replace it. The not-installed error now says to reinstall rather than add devDependencies.
  • Regression test in dev-emulators: a 100 KiB bind parameter round-trips and a second connection still works. Verified it fails against @prisma/dev 0.20.0 with the reported Connection terminated unexpectedly.
  • scripts/check-prisma-dev-pin.test.mjs (runs under pnpm test:scripts in CI) keeps the public manifest, the local target, and the emulator tests on one range and never below 0.21.0.
  • The stale-record emulator test now excludes every registry-claimed port through registryClaimedPorts; it previously skipped streams ports and failed on a developer machine with such a record.
  • Skill and running-locally guide say which @prisma/dev the emulator uses.

Verification

  • @internal/local-target and @internal/dev-emulators suites, pnpm test:scripts, pnpm lint:deps, typecheck: green.
  • A fresh app depending only on the packed @prisma/composer-prisma-cloud, prisma 8.0.0-rc.13 and pg, installed under both node-linker=hoisted and node-linker=isolated, resolves @prisma/dev 0.25.2 from Composer's package (under isolated the app has no @prisma/dev of its own) and round-trips a 100 KiB parameter.
  • Alchemy: no Composer code uses alchemy's lib/Prisma/PrismaDevDatabase.js; the local target's LocalDatabaseProvider replaces alchemy's Prisma.Database provider, so no alchemy issue is needed.

Follow-up in prisma/asks

After this ships: upgrade Composer, delete patches/@electric-sql__pglite-socket@0.0.20.patch and its patchedDependencies entry, and drop the gotcha.

🤖 Generated with Claude Code

…uns on

Any Postgres message over 64 KiB killed the local emulator: the published
@prisma/composer-prisma-cloud never declared @prisma/dev, and the local
target resolved it from the application, so apps got whatever copy alchemy's
^0.20.0 range dragged in — a release whose pglite-socket hands each raw TCP
chunk to PGlite as a whole message. The migration runner's contract snapshot
crosses that size early, after which every connection is refused.

- @prisma/composer-prisma-cloud and @internal/local-target declare
  @prisma/dev ^0.25.2 as a runtime dependency.
- The local target resolves @prisma/dev from Composer's own package only; the
  application fallback is gone, and the not-installed error says to reinstall
  instead of adding devDependencies.
- Regression test: a 100 KiB bind parameter round-trips through the emulator
  and a second connection still works. It fails against @prisma/dev 0.20.0.
- scripts/check-prisma-dev-pin.test.mjs keeps the public manifest, the local
  target, and the emulator tests on one range, never below 0.21.0.
- The stale-record test excludes every registry-claimed port via
  registryClaimedPorts (it skipped streams ports and tripped on a developer
  machine's records).
- Skill and running-locally guide say which @prisma/dev the emulator uses.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Signed-off-by: willbot <w.a.madden+machine@gmail.com>
Signed-off-by: Will Madden <madden@prisma.io>
@prisma-gizmo

prisma-gizmo Bot commented Sep 17, 2026

Copy link
Copy Markdown

✅ Gizmo reviewed edcc39e — posted 0 inline comment(s) this pass.

Open findings: none

Change walkthrough

Change walkthrough

This PR makes Composer the owner of the @prisma/dev version its local Postgres emulator runs on, instead of resolving it from the consuming app. The motivation is a pglite-socket 0.0.20 defect (fixed in @prisma/dev 0.21.0) that crashed the emulator on any Postgres message over 64 KiB — a size any app's migration snapshot can exceed — which apps hit because Composer's published package never declared @prisma/dev and inherited whatever the app's dependency tree supplied (or nothing, under an isolated linker).

Dependency ownership. packages/9-public/composer-prisma-cloud/package.json:46 and local-target/package.json:21 now declare @prisma/dev ^0.25.2 as a runtime dependency. postgres.ts drops the two-step app/CLI-relative resolution and resolves only from Composer's own install via createRequire(import.meta.url); the daemon still imports @prisma/dev dynamically from the caller-resolved path, so postgres-main.ts keeps no dependency of its own. Because the module is only ever referenced as a require.resolve string and a dynamic import of that result, nothing in the published bundle needs externalizing — the declaration in the published manifest is what makes resolution work under hoisted and isolated linkers alike. The not-installed error now points at a broken install (reinstall) rather than asking users to add a devDependency.

Tests. postgres.test.ts adds a live regression test — a 100 KiB bind parameter round-trips and a second connection still works — plus the module-resolution suite rewritten to assert Composer-owned, cwd-independent resolution. The stale-record port test now reuses registryClaimedPorts (the daemon's own pick logic) instead of a hand-rolled scan.

Guard rail. check-prisma-dev-pin.test.mjs runs under pnpm test:scripts and keeps the public package, local-target, and the emulator tests on one range, never below 0.21.0.

Docs. The running-locally guide and the core-concepts skill drop the "add @prisma/dev to devDependencies" instruction and document Composer-owned resolution.

@coderabbitai

coderabbitai Bot commented Sep 17, 2026

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Advanced

Run ID: cacd6458-f059-43a6-9119-a349810ab231


Comment @coderabbitai help to get the list of available commands.

@pkg-pr-new

pkg-pr-new Bot commented Sep 17, 2026

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/@prisma/composer@298
npm i https://pkg.pr.new/@prisma/composer-cli@298
npm i https://pkg.pr.new/@prisma/composer-prisma-cloud@298

commit: edcc39e

@prisma-gizmo prisma-gizmo Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

New findings: 🟡 1 minor · trace

Comment thread scripts/check-prisma-dev-pin.test.mjs Outdated
The regex only matched two-digit minors, so a legitimate bump to 0.100.0
would have failed the guard with an unhelpful TypeError.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Signed-off-by: willbot <w.a.madden+machine@gmail.com>
Signed-off-by: Will Madden <madden@prisma.io>

@prisma-gizmo prisma-gizmo Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

New findings: none · trace

@prisma-gizmo prisma-gizmo Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

All Gizmo review threads are resolved and the head commit has been reviewed. Approving.

@prisma-gizmo prisma-gizmo Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

New findings: none · trace

@prisma-gizmo prisma-gizmo Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

All Gizmo review threads are resolved and the head commit has been reviewed. Approving.

@wmadden-electric
wmadden-electric merged commit 5ef5de7 into main Sep 18, 2026
21 checks passed
@wmadden-electric
wmadden-electric deleted the claude/postgres-64kib-crash-d04bff branch September 18, 2026 11:37
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.

2 participants