Prisma Release Notes
139 release notes curated from 51 sources by the Releasebot Team. Last updated: Aug 10, 2026
- Aug 9, 2026
- Date parsed from source:Aug 9, 2026
- First seen by Releasebot:Aug 10, 2026
v8.0.0-rc.1-dev.10
Prisma adds @nocheck to opt columns out of generated CHECK constraints.
feat(sql): @nocheck opts a column out of generated CHECK constraints …
Original source - Aug 9, 2026
- Date parsed from source:Aug 9, 2026
- First seen by Releasebot:Aug 10, 2026
v8.0.0-rc.1-dev.9
Prisma adds contract.json JSON schema generation.
chore(sql-contract-ts): generate contract.json JSON schema from arkty…
Original source All of your release notes in one feed
Join Releasebot and get updates from Prisma and hundreds of other software products.
- Aug 7, 2026
- Date parsed from source:Aug 7, 2026
- First seen by Releasebot:Aug 8, 2026
v8.0.0-rc.1
Prisma ships the v8 release candidate with new versioning, bigint aggregate results, a split SQL driver interface, and Prisma Next init workflow updates. It also fixes contract emit, self-relation aliasing, many-to-many reducers, and driver error reporting.
v8.0.0-rc.1
This is the first release on the v8 release-candidate line: releases are now versioned 8.0.0-rc.N instead of 0.x minors. It also makes every aggregate read back through the codec its target declares — count() returns a bigint — splits the SQL driver interface into a row-streaming call and a statistics call, and fixes four defects in query planning, emit, and driver error reporting.
The v8 release-candidate line
Releases are now versioned 8.0.0-rc.1, 8.0.0-rc.2, and so on, with the counter advancing on every release. "The v8 RC" is the product name; the number underneath iterates freely, so there is no promise that the last RC before 8.0.0 final is numbered rc.1. There are no further 0.x minors. The policy is written up in docs/oss/versioning.md. (#29899)
For every package this repository publishes, latest keeps tracking the newest release, RC included. These package names have no pre-v8 stable audience to protect — a bare npm install of one of them was already an early-access install, and still is. The bare prisma package is not published from this repository; its v8 CLI shim lives in prisma/prisma-cli.
Existing installs are not moved onto the RC line by npm update. Lockfiles pin resolved versions, and a ^0.x range can never match a 8.0.0-rc.N pre-release, because pre-releases do not satisfy stable ranges. Only a fresh install, or an explicit version change on your side, lands on the RC.
Development builds move to the same line: every push to main that does not change the root version publishes 8.0.0-rc.X-dev.N under the dev dist-tag.
An RC respin may still contain breaking changes. Until 8.0.0 final ships, the pre-1.0 latitude documented in docs/oss/versioning.md carries over: a new rc.N may remove or rename APIs, change the semantics of existing ones, or change the contract format. Read the breaking-changes section of each release before you upgrade.
Breaking changes
Aggregate results carry the codec their target declares — an aggregate is now read back through the codec its target declares for that result rather than through whatever the driver handed over, so aggregate application types change. count() is a bigint on both PostgreSQL and SQLite, at the top level and inside an include, and an empty relation reads 0n. On PostgreSQL, sum over int2/int4 widens to a bigint, while sum(int8) and avg over any integer are numeric and read as exact decimal strings; min/max keep the column's own type, except over varchar, which returns text. On SQLite, sum over an integer column is a bigint and avg is always a number. Sweep your code for equality and arithmetic against an aggregate result (count === 2 is false when count is 2n) and for JSON.stringify over one (it throws on a bigint). having(...) operands are the exception and stay plain numbers — they are compared inside SQL and never cross a codec. Regenerate your contracts (prisma-next contract emit): contract.d.ts gains an AggregateTypes block that both the ORM and the SQL builder resolve result types from, and against an older contract an aggregate resolves to never in the ORM and unknown in the SQL builder. The type is not the only guard: an aggregate whose operation and input codec the composed target does not declare is rejected before the query runs, with the error code ORM.AGGREGATE_UNSUPPORTED. See the upgrade recipe and the extension-author recipe. (#29867)
Before:
const rows = await posts.include('comments', (comments) => comments.count()).all(); rows[0].comments === 2; // number; 0 when the relation is emptyAfter:
const rows = await posts.include('comments', (comments) => comments.count()).all(); rows[0].comments === 2n; // bigint; 0n when the relation is emptyThe SQL driver interface splits row streaming from statement statistics — SqlQueryable (exported from @internal/sql-relational-core/ast) is now two methods wide: query() streams rows and execute() returns { affectedRows }. The separate prepared-execution method is gone; a prepared plan is expressed by an optional preparedStatementHandle on the request instead, and a driver branches on whether that property is undefined. Application code, query results, and the contract format are unaffected — this only matters if you implement or wrap SqlQueryable yourself, in which case update your implementation to the two-method shape. There is no upgrade recipe entry for this; the change is the interface itself. (#29907)
Before:
interface SqlQueryable { execute<Row>(request: SqlExecuteRequest): AsyncIterable<Row>; executePrepared<Row>(request: PreparedExecuteRequest): AsyncIterable<Row>; query<Row>(sql: string, params?: readonly unknown[]): Promise<SqlQueryResult<Row>>; }After:
interface SqlQueryable { query<Row>(request: SqlExecuteRequest): AsyncIterable<Row>; execute(request: SqlExecuteRequest): Promise<SqlStatementStats>; }Features
prisma-next init installs one prisma-8 skill instead of eleven per-workflow skills, and removes the retired skill directories from every agent's install root on each run. Each skill is now installed by name — prisma-8, prisma-next-upgrade, and prisma-8-extension-upgrade — rather than by matching a wildcard against a directory, so a new skill landing beside them is not picked up by accident. (#29853)
Fixes
A column, table, or model mapped to a name that is not a bare TypeScript identifier — @map("has space"), @@map("data rows") — now emits a quoted property key in contract.d.ts instead of producing a syntactically invalid file that killed contract emit. String literals in emitted TypeScript also survive control characters and line separators, which previously produced the same failure by a different route. (#29889, #29898)
Nested some/every/none predicates over a self-referential relation now keep a distinct SQL alias at every level, so an inner scope no longer shadows the parent it is supposed to correlate against. This covers one-to-one, many-to-one, one-to-many, implicit many-to-many, and explicit-junction many-to-many relations in both directions, and relations whose physical tables share a bare name across namespaces. (#29900)
Scalar reducers on a many-to-many include — count(), sum(), avg(), min(), max() — now traverse the junction table instead of emitting a predicate against a foreign-key column that only exists on the junction, so a filtered relation count over a many-to-many relation returns the right number. (#29888)
A failed retry of a stale PostgreSQL prepared statement now surfaces a structured error envelope with the code DRIVER.PREPARE_FAILED, carrying the normalized driver error as its cause, instead of an unlabelled failure. (#29907)
Original source - Aug 7, 2026
- Date parsed from source:Aug 7, 2026
- First seen by Releasebot:Aug 8, 2026
v8.0.0-rc.1-dev.7
Prisma routes migration and db commands through the control-api seam.
Route migration/db commands through the control-api seam (TML-3173) (…
Original source - Aug 7, 2026
- Date parsed from source:Aug 7, 2026
- First seen by Releasebot:Aug 8, 2026
v8.0.0-rc.1-dev.6
Prisma refactors generic error handling with explicit codes and better cause support.
refactor(errors): explicit codes on the generic error path, cause sup…
Original source Similar to Prisma with recent updates:
- Smokeball release notes137 release notes · Latest Aug 4, 2026
- Cosmolex release notes20 release notes · Latest Jul 30, 2025
- PracticePanther release notes35 release notes · Latest Jul 7, 2026
- Salesforce release notes58 release notes · Latest Jul 1, 2026
- Microsoft release notes769 release notes · Latest Aug 5, 2026
- Zoom release notes205 release notes · Latest Jul 27, 2026
- Aug 7, 2026
- Date parsed from source:Aug 7, 2026
- First seen by Releasebot:Aug 8, 2026
v8.0.0-rc.1-dev.5
Prisma adds in-place renaming for SQL check constraints when only the prefix changes.
feat(sql): rename check constraints in place when only their prefix c…
Original source - Aug 7, 2026
- Date parsed from source:Aug 7, 2026
- First seen by Releasebot:Aug 8, 2026
v8.0.0-rc.1-dev.4: TML-3163: add BigIntNumber and UnboundedInt column types (#29902)
Prisma adds integer representation presets for PostgreSQL and SQLite, supporting safe-range JavaScript numbers, arbitrary-precision PostgreSQL integers, and stricter validation for unsafe or out-of-range values.
Linked issue
Refs
TML-3163
— slice 06 of the Codec JSON projections project. This unblocks TML-3165, whose aggregate defaults consume the new codec IDs.
This PR makes integer representation a per-column contract choice without changing the lossless BigInt default.
model Meter { id Int @id peak BigIntNumber lifetime UnboundedInt }peak reads and writes as a JavaScript number, throwing outside ±(2^53 − 1) instead of rounding. lifetime uses PostgreSQL unconstrained numeric storage and round-trips integral values as exact JavaScript bigint values at arbitrary magnitude.
Changes
Integer representation codecs: Adds pg/int8number@1 and sqlite/bigintnumber@1 for safe-range JavaScript numbers, plus PostgreSQL pg/unboundedint@1 for arbitrary-precision integral values. Encode and decode paths reject non-integral or out-of-range values with structured RUNTIME.ENCODE_FAILED / RUNTIME.DECODE_FAILED errors.
Target-scoped authored types: PostgreSQL contributes BigIntNumber and UnboundedInt; SQLite contributes only BigIntNumber. These are top-level zero-argument type constructors, so PSL fields use ordinary bare type syntax and retain normal optional/default/list composition. The corresponding codecs keep targetTypes: [], leaving canonical introspection unchanged (int8 → BigInt, numeric → Numeric).
TypeScript authoring: The composed callback exposes type.BigIntNumber() and PostgreSQL type.UnboundedInt() for registered storage types used through field.namedType(...). Direct authoring remains available through field.column(pgInt8NumberColumn()), field.column(pgUnboundedIntColumn()), and field.column(sqliteBigintNumberColumn()).
Aggregate typing: Adds target-probed sum / avg rows for the new codecs. min / max continue to resolve through the numeric-trait self fallback. PostgreSQL sum over UnboundedInt remains exact as bigint; widening results use the target's canonical numeric codec.
End-to-end proof and migration guidance: Adds PostgreSQL and SQLite emitted PSL fixtures, runtime and type-level ORM coverage, codec and aggregate conformance cases, reference documentation, and no-op upgrade declarations on the current 8.0.0-rc.1 → 8.0.0-rc.2 edge because existing source requires no migration.
Why
The database storage type cannot identify the intended application representation: PostgreSQL int8 may be read as lossless bigint or guarded number, while numeric may represent general decimal text or integral bigint. Giving the alternative codecs native-type claims would make reverse resolution and introspection ambiguous.
Target-contributed type constructors separate the two concerns cleanly: authors explicitly select the application representation, while introspection continues to emit the canonical type for each storage type. This also uses Prisma Next's surviving type-constructor abstraction rather than field-template machinery that would incorrectly impose preset-specific field restrictions.
BigIntNumber deliberately projects database-produced JSON as a JSON number. The safe-range guard is sound because ECMAScript numbers are IEEE 754 binary64, 2^53 is exactly representable, and monotone rounding cannot move an out-of-range integer into the accepted safe range. Values that could lose precision always throw.
Review notes
Registering the numeric codecs radiates additive aggregateTypes.byCodec rows into generated contracts even when a schema does not use the authored types. Existing entries remain unchanged.
SQLite has no UnboundedInt because it has no lossless unbounded integer storage.
On a flat SQLite read, node:sqlite may reject an out-of-range INTEGER before the codec runs; include/database-JSON reads still surface the structured codec error.
The integer-representation fixture outputs remain semantically unchanged after moving from call syntax to bare types; canonical regeneration adds only the expected globally radiated aggregate rows to one previously stale fixture.
Validation
Post-rebase validation against current origin/main:
- pnpm build
- pnpm --dir test/integration typecheck
- Fresh PR Type Check job
- pnpm lint:deps — 1,921 modules / 2,934 dependencies, no violations
- pnpm lint:skills
- pnpm lint:docs — passes with existing README warnings
- pnpm fixtures:check
- pnpm check:upgrade-coverage
- PostgreSQL and SQLite target, scalar-parity, codec-conformance, aggregate-conformance, and contract-TS suites
- Package-local typechecks for the changed target, extension, adapter-testkit, and contract-TS packages
- Focused integer-representation integration: all 6 tests pass with no type errors
- Stale authoring-call and preset-guidance rg gates
- git diff --check
All PR-scoped gates pass, including the fresh CI Type Check. Two local pnpm typecheck attempts hit a Turbo output-ordering race while concurrent builds cleaned package dist self-imports (pgvector/pack, then supabase/runtime); CI's isolated Type Check completes successfully.
Checklist
- Commits are signed off per the DCO.
- Tests cover target availability, TypeScript authoring, codec boundaries, emitted contracts, runtime reads/writes, includes, and aggregate result types.
- Upgrade declarations classify the generated aggregate-row additions as inert for existing source on the current release edge.
Summary by CodeRabbit
New Features
Added integer representation presets for PostgreSQL and SQLite, supporting safe-range JavaScript numbers and arbitrary-size PostgreSQL integers.
Added validation for unsafe, fractional, and out-of-range values.
Extended avg, min, max, and sum aggregates with nullable results and large-value support.
Added nested-read support and improved inferred types for these representations.
Documentation
Expanded guidance on integer presets, aggregate behavior, JSON formats, and validation errors.
Tests
Added comprehensive unit, integration, and aggregate conformance coverage.
Signed-off-by: Alexey Orlenko's AI Agent [email protected]
Original source - Aug 7, 2026
- Date parsed from source:Aug 7, 2026
- First seen by Releasebot:Aug 8, 2026
v8.0.0-rc.1-dev.3
Prisma adds SQL contract support for declaring every CHECK constraint by name.
feat(sql): declare every CHECK constraint in the contract, named by i…
Original source - Aug 7, 2026
- Date parsed from source:Aug 7, 2026
- First seen by Releasebot:Aug 8, 2026
v8.0.0-rc.1-dev.2
Prisma fixes driver-postgres transaction integrity and Supabase support.
fix(driver-postgres): direct-driver transaction integrity + supabase …
Original source - Aug 7, 2026
- Date parsed from source:Aug 7, 2026
- First seen by Releasebot:Aug 8, 2026
v8.0.0-rc.1-dev.1: fix(sql-orm-client): reload rows by Bytes identities (#29910)
Prisma fixes SQL ORM mutation reloads and upsert conflicts by making select-plan binding codec-aware, so Bytes primary keys and repeated upserts now reload correctly. The release also tightens raw state filter handling and ships related CI and driver test repairs.
Linked issue
n/a — small change
At a glance
const upsertByteRow = () => db.public.TestByteId.upsert({ create: { bytes: byteId }, update: {}, conflictOn: { bytes: byteId }, }); await upsertByteRow(); await upsertByteRow();The second upsert previously raised ORM.MUTATION_ROW_MISSING because its Bytes conflict value was not encoded through the column codec during the reload query.
Decision
This PR fixes SQL ORM mutation reloads by contract-binding every CollectionState filter at the shared select-plan boundary. Internal primary-key and upsert-conflict reloads now receive the same codec-aware parameterization as fluent query filters, without adding a Bytes-specific branch.
Reviewer notes
The behavior change is broader than the two Bytes regressions: any unbound literal entering a select through raw collection state now becomes a typed parameter. Existing ParamRef filters are preserved by the idempotent binding path.
Binding deliberately happens before table-reference remapping so codec lookup sees the contract's real storage table; self-relation and include aliases are applied afterward as before.
Rebasing exposed driver-SPI regressions in the CI baseline. This branch repairs them rather than leaving the PR red: Supabase role sessions again implement normal and prepared runtime execution, cache tests observe the driver's query path, the PGlite ORM harness avoids cursor-backed transaction leakage, DRIVER.PREPARE_FAILED is documented, and PostgreSQL driver's new prepared branches meet the coverage gate.
Real-Supabase acceptance fixtures now use unique emails and delete dependent profiles before auth users, preventing a failed case from poisoning later tests.
No public API, contract format, migration, or downstream translation changes.
How it fits together
Internal mutation reloads build shorthand identity criteria that can reach CollectionState.filters as literal expressions.
buildStateWhere now passes all state filters through the existing contract-aware binder before alias remapping.
The binder resolves the compared column's codec and emits a codec-bearing parameter, allowing PostgreSQL Bytes values to remain Uint8Array wire values instead of becoming JSON-shaped literals.
Both affected Prisma ports now run as ordinary passing tests, and their entries are removed from the expected-failure ledger.
Behavior changes & evidence
Repeated upserts on a Bytes unique value return the existing row instead of throwing. The shared select-plan fix is in query-plan-select.ts, with end-to-end evidence in bytes-upsert.test.ts.
Nested creates can reload parents identified by Bytes primary keys. The mutation reload path now receives a typed Bytes parameter, verified by issues-27455-bytes-id.test.ts.
Raw state filters are bound at select compilation. The focused plan-level regression in query-plan-select.test.ts proves an unbound literal becomes a codec-bearing ParamRef and appears in the plan parameters.
The failure ledger again describes only active failures. Both resolved entries are removed from failing.md, reducing it from 45 to 43 cases.
The rebased driver split remains usable across CI surfaces. Supabase role-bound scopes delegate normal and prepared execution through the correct raw scope, cache integration observes driver.query, transactional PGlite tests use the non-cursor path, the new prepared-statement error has reference documentation, and driver tests cover empty prepared streams and non-Error connection-state checks.
Testing performed
pnpm build — 86/86 tasks passed.
pnpm typecheck — 165/165 tasks passed after the build.
pnpm lint — 101/101 tasks passed.
pnpm --filter @internal/sql-orm-client test — 62 files, 696 tests passed.
pnpm --filter @internal/sql-orm-client test test/query-plan-select.test.ts — 32 tests passed on the final test shape.
pnpm --filter @internal/extension-supabase test — 17 files, 89 tests passed.
pnpm --filter @internal/driver-postgres test:coverage — 13 files and 131 tests passed; branch coverage is 95.71%.
pnpm --filter integration-tests exec vitest run test/cross-package/middleware-cache.test.ts test/sql-orm-client/mn-nested-write.test.ts --reporter=verbose — 26 tests passed.
pnpm --filter integration-tests exec vitest run test/ports/prisma/functional/bytes-upsert/bytes-upsert.test.ts test/ports/prisma/functional/issues-27455-bytes-id/issues-27455-bytes-id.test.ts --reporter=verbose — 2 tests passed.
Upgrade coverage, error-reference verification, cast ratchet, dependency lint, focused Biome checks, and pre-commit validation passed.
Skill update
Recorded as incidental changes: [] diffs in skills/prisma-8-extension-upgrade/upgrades/0.17-to-0.18/instructions.md and skills/prisma-next-upgrade/upgrades/0.17-to-0.18/instructions.md.
This fix changes no user or extension-author API and requires no downstream source translation.
Alternatives considered
Bind only in #reloadMutationRowByCriterion. This would fix the two observed mutation paths but leave other internal producers of raw select state exposed to the same missing-binding bug.
Teach the PostgreSQL literal renderer to special-case Uint8Array. This would bypass the contract codec and parameter system, duplicate target-specific encoding policy, and leave other typed literals inconsistent.
Checklist
All commits are signed off (git commit -s) per the DCO.
I read CONTRIBUTING.md and the change is scoped to one logical concern.
Tests are updated.
PR title follows the agreed no-ticket exception; this change has no Linear issue.
The Skill update section is filled in.
Signed-off-by: Steven McClankerton [email protected]
Co-authored-by: Steven McClankerton [email protected]
Original source - Aug 7, 2026
- Date parsed from source:Aug 7, 2026
- First seen by Releasebot:Aug 8, 2026
v0.17.0-dev.12
Prisma updates its roadmap docs to reconcile statuses with code and Linear and drop stale items.
docs(roadmap): reconcile statuses with code and Linear; drop stale ta…
Original source - Aug 6, 2026
- Date parsed from source:Aug 6, 2026
- First seen by Releasebot:Aug 7, 2026
v0.17.0-dev.10: test(mongo): enforce composite validators in port suites (#29908)
Prisma expands MongoDB contract validation in its test harness, provisioning fresh databases through the migration planner and runner before runtime writes. Required composite null writes now fail as expected across create, update, bulk, and upsert paths.
Linked issue
n/a — no Linear ticket
At a glance
const connectionUri = replSet.getUri(dbName); await pushContract(connectionUri, options.contractJson); client = new MongoClient(connectionUri);Mongo Prisma-port suites now provision their emitted contract before exercising runtime writes.
Decision
This PR provisions every fresh Mongo Prisma-port database through Prisma Next’s Mongo migration planner and runner before a test receives its runtime handle. The resulting collection validator rejects null writes to required composite objects and lists, so 24 required-composite compatibility cases now pass instead of being expected failures.
Summary
The Mongo test harness now validates the actual contract-to-migration path rather than operating against an unvalidated memory-server database.
Reviewer notes
pushContract() deliberately uses the Mongo control-plane planner and runner rather than a test-only createCollection() call, so the suites cover the product migration path that derives validators from contracts.
The same database-specific replica-set URI is used for provisioning, raw Mongo access, and the Prisma Next runtime; validators and test operations therefore target the same database.
The two remaining composite-suite expected failures are intentionally unchanged: optional composite unset() removes the Mongo field instead of returning Prisma-compatible null.
How it fits together
The shared Mongo harness builds a control stack, deserializes each emitted contract, introspects the empty database, and plans an additive greenfield migration.
It executes that plan with the standard Mongo migration runner before creating the raw client and runtime, which creates the contract-derived collection validator.
Object and list composite create, createMany, update, updateMany, and upsert tests now assert the server-side rejection of invalid required-composite null writes.
The expected-failure ledger removes the resolved cases, and the Mongo scorecard records the runtime guarantee as supported.
Behavior changes & evidence
Mongo port suites install collection validators before runtime operations.
test/integration/test/ports/_harness/mongo.tsplans and applies the emitted contract through the production migration interfaces. Required object and list create paths now demonstrate the resulting rejection in
composites-object-create.test.tsand
composites-list-create.test.ts.Required composite null writes are now passing compatibility coverage. Object and list create, createMany, update, updateMany, and upsert suites promote 24 cases from it.fails to normal tests, including
composites-object-update.test.tsand
composites-list-upsert-update.test.ts.Compatibility documentation records the resolved gap.
failing.mdretains only the two optional-composite unset() differences, while07-mongodb-query-and-orm.mdmarks required-composite null rejection as supported.
Skill update
n/a — internal test harness and documentation only
Testing performed
pnpm --filter integration-tests typecheck
pnpm --filter integration-tests lint
pnpm lint:deps
Mongo Prisma-port suites: 23 suites, 106 passed cases, and 2 intentional expected failures
Commit hook: Biome format/check and focused dependency lint for the staged TypeScript files
Alternatives considered
Manually create Mongo collections in the test harness: rejected because it would bypass the contract, planner, and runner path that produces the validator in real use.
Add a separate client-side nullability guard: rejected because these ports need to verify MongoDB’s contract-derived server-side enforcement.
Checklist
All commits are signed off (git commit -s) per the DCO. The DCO status check will block merge if any commit is missing a Signed-off-by: trailer.
I read CONTRIBUTING.md and the change is scoped to one logical concern.
Tests are updated (or n/a if the change is doc-only / refactor with no behavioural delta).
The PR title is in TML-NNNN: <sentence-case title> form (no Linear ticket exists for this change).
The Skill update section above is filled in (or stated n/a — internal only).
Summary by CodeRabbit
Bug Fixes
MongoDB now consistently rejects null values written to required composite fields and lists across create, update, bulk, and upsert operations.
Required composite validation behavior is now aligned across runtime operations.
Tests
Expanded integration coverage for null-value rejection and MongoDB-backed migration setup.
Updated expected outcomes for composite object and list operations.
Documentation
Updated the MongoDB support scorecard to reflect supported required-composite null validation.
Signed-off-by: Steven McClankerton [email protected]
Co-authored-by: Steven McClankerton [email protected]
Original source - Aug 6, 2026
- Date parsed from source:Aug 6, 2026
- First seen by Releasebot:Aug 7, 2026
v0.17.0-dev.8: TML-3171: Fix nested self-relation predicates in SQL ORM (#29900)
Prisma improves self-relation query handling with scope-safe SQL aliases, fixing nested filters, joins, includes, counts, and aggregates across one-to-one, one-to-many, and many-to-many relations. It also adds broader integration coverage for these cases.
Linked issue
Refs
TML-3171
Fixes prisma/prisma-next#980
At a glance
person.following.some((followed) => followed.following.some((nested) => nested.name.eq('Dex')), )This depth-two self-relation predicate previously reused the physical
people table reference across scopes, allowing the inner source to
shadow the correlated parent.Summary
Self-relation predicates now preserve their lexical SQL scopes across
repeated nesting, so filtering, joins/includes, and aggregation work
across ordinary, navigable M:N, and explicit-junction relations. The
integration matrix exercises at least two self-relation levels.Decision
This PR ships three connected changes:
- Separate physical storage coordinates from the lexical SQL table
reference carried by each model accessor. - Allocate distinct relation and junction aliases from one shared
scope-aware allocator as nested predicates are built. - Add a real Postgres/PGlite integration matrix for every supported
self-relation shape in both directions. Across the matrix, the tests
cover depth-two traversal, joins/includes, some/none/every, and
aggregation.
Reviewer notes
The emitted fixture files are the bulk of the diff; the authored
fixture is
test/integration/test/sql-orm-client/fixtures/self-relations/contract.prisma.Generated aliases such as __orm_rel_1 and __orm_junction_2 are
internal SQL identifiers. They are allocated monotonically per root
accessor and only replace a table name when that name collides with a
visible source.This is an internal query-planning fix with no public API or
contract-format change.The first CI run exposed two multi-schema ports whose it.fails
markers had become stale because this fix makes their
identical-table-name predicates pass. They are now ordinary passing
tests and their entries have been removed from
failing.md.The required extension-upgrade declaration is recorded as an
incidental changes: [] note in
skills/prisma-8-extension-upgrade/upgrades/0.17-to-0.18/instructions.md;
no extension-author migration is required.How it fits together
- model-accessor.ts
creates a root scope containing the physical source, its current SQL
reference, visible sources, and a shared alias allocator. - Each nested relation appends its child source and, for navigable M:N,
its junction source. A colliding physical table name receives a fresh
lexical alias while the immediate parent's actual SQL reference remains
available for correlation. - Scalar fields emit ColumnRef values against the lexical reference,
while field, column, and codec metadata continue resolving against
physical storage coordinates. - Relation predicates retain these already-scoped expressions through
construction, preserving which references belong to the child and which
correlate to an ancestor. - The emitted self-relations
fixture
drives the full runtime matrix in
self-relations-matrix.test.ts.
Behavior changes & evidence
M:1 and 1:M self-relations now filter and include in both directions
across multiple nesting levels; the scope handling in
model-accessor.ts
is exercised with some, none, every, and filtered aggregate counts
in
self-relations-matrix.test.ts.1:1 self-relations now preserve correlation through owning-to-reverse
and reverse-to-owning depth-two cycles;
model-accessor.ts
is covered with nested includes and filtered aggregation in
self-relations-matrix.test.ts.Navigable M:N self-relations—the implicit collection surface backed by
a junction contract entity—now allocate independent child and junction
scopes in both directions;
model-accessor.ts
is exercised with depth-two predicates, nested includes, relation-scoped
counts, single-query execution, and an emitted INNER JOIN through
person_follows in
self-relations-matrix.test.ts.Explicit-junction M:N traversal now works from source to target and
target to source; the relation scope construction in
model-accessor.ts
is covered with nested related models, relation-scoped counts, and
sum(weight) in
self-relations-matrix.test.ts.Cross-namespace relations whose physical tables share the same bare
name now preserve their distinct scopes;
model-accessor.ts
is covered by the promoted read and update cases in
multi-schema.test.ts.The alias allocator in
model-accessor.ts
has focused coverage in
model-accessor.test.ts,
verifying that depth-two ordinary and repeated M:N predicates correlate
to their immediate parent and receive distinct aliases.Testing performed
Passed after rebasing onto the latest origin/main:
- pnpm build — run by the integration pretest, 86 tasks
- pnpm --filter integration-tests test test/ports/prisma/functional/multi-schema/multi-schema.test.ts test/sql-orm-client/self-relations-matrix.test.ts — 2 files, 16 tests
- pnpm --filter @internal/sql-orm-client test model-accessor.test.ts —
1 file, 38 tests - pnpm --filter integration-tests lint — 667 files
- pnpm check:upgrade-coverage --mode pr
- git diff --check origin/main...HEAD
The original implementation validation also passed package and
integration typechecks, SQL ORM and integration lints, dependency lint,
the full SQL ORM unit suite (62 files, 693 tests), focused self-relation
integration tests, and fixture emission without drift.Skill update
No migration action is required. The incidental extension-substrate
declaration is recorded in
skills/prisma-8-extension-upgrade/upgrades/0.17-to-0.18/instructions.md.Alternatives considered
Derive aliases from relation names, such as __child. This
handles one nesting level but repeats the same alias when a
self-relation is traversed again and does not independently scope M:N
junctions.Recursively rewrite ColumnRef table names after building a
predicate. The rewrite cannot reliably distinguish references belonging
to the current child from correlated references belonging to an
ancestor, so it becomes incorrect as soon as scopes repeat.Checklist
- All commits are signed off (git commit -s) per the
DCO. - I read CONTRIBUTING.md and the change is
scoped to one logical concern. - Tests are updated.
- The PR title is in TML-NNNN: form.
- The Skill update section above is filled in.
Summary by CodeRabbit
Bug Fixes
Improved SQL ORM queries involving self-referential relationships.
Fixed nested relation filters and joins across one-to-one,
one-to-many, and many-to-many relationships.
Prevented ambiguous results when repeating nested relations.
Fixed relation filtering and updates when identical table names are
used across schemas.
Improved support for nested includes, counts, aggregates, and
bidirectional relation queries.Tests
Added coverage for self-relations, junction-table relationships,
nested includes, aggregates, query results, single-query execution, and
multi-schema operations.Signed-off-by: Steven McClankerton [email protected]
Co-authored-by: Steven McClankerton [email protected]
Original source - Aug 5, 2026
- Date parsed from source:Aug 5, 2026
- First seen by Releasebot:Aug 5, 2026
v0.17.0-dev.6
Prisma quotes non-identifier column, table, and model names in contract.d.ts.
Quote non-identifier column, table, and model names in contract.d.ts …
Original source - Aug 5, 2026
- Date parsed from source:Aug 5, 2026
- First seen by Releasebot:Aug 5, 2026
v0.17.0-dev.5: skills: consolidate 11 usage skills into skills/prisma-next (#29853)
Prisma consolidates Prisma Next skills into one primary installable skill with separate upgrade skills, making installs explicit and safer. Prisma Next init now cleans up retired skill directories automatically, and the docs add new guidance for the streamlined layout.
Linked issue
n/a — small change
At a glance
Before, every skill install picked up whatever matched a wildcard on its subpath:
skills add prisma/prisma-next/skills#v0.16.0 --agent cursor claude-code codex windsurf --skill '*' -y skills add prisma/prisma-next/skills/upgrade --agent cursor claude-code codex windsurf --skill '*' -y skills add prisma/prisma-next/skills/extension-author --agent cursor claude-code codex windsurf --skill '*' -yNow every install names its skill explicitly, and all three sources live under the same skills subpath:
skills add prisma/prisma-next/skills#v0.16.0 --agent cursor claude-code codex windsurf --skill prisma-next -y skills add prisma/prisma-next/skills --agent cursor claude-code codex windsurf --skill prisma-next-upgrade -y skills add prisma/prisma-next/skills --agent cursor claude-code codex windsurf --skill prisma-next-extension-upgrade -yThe wildcard used to matter because skills/ held eleven separate usage skills plus the two upgrade skills. It's now one usage skill (prisma-next) and two upgrade skills, so naming the skill directly is both simpler and safer against future siblings landing under the same subpath.
Summary
The usage surface was eleven separate skills (prisma-next-quickstart, prisma-next-contract, prisma-next-queries, …) plus a thin router. Agent runtimes match a skill against the user's prompt by a single
description:field per skill, so a cluster this size forces each description to carve out its own trigger territory — and the boundaries drift and misfire as the cluster grows. This PR collapses the cluster into one installable skill with progressive disclosure into reference files, and documents the design principles behind that shape so future changes hold the line.Decision
Consolidate the 11-skill usage cluster into one skill — skills/prisma-next/. SKILL.md is the only always-loaded content (activation description + routing table + canonical mental model); every retired skill's body becomes a reference file under skills/prisma-next/references/.md, loaded only when its routing-table row matches.
Hoist the two upgrade skills to top-level siblings — skills/prisma-next-upgrade/ and skills/prisma-next-extension-upgrade/. They stay separate from the usage skill because their install ref policy differs (always main, never version-pinned).
Update the CLI's skill installer to name each skill explicitly (--skill ) instead of a subpath wildcard, and to remove retired per-workflow skill directories from every agent's install root on every prisma-next init run.
Document the design principles behind this shape in skills/DEVELOPING.md — one skill not a cluster, progressive disclosure with explicit length budgets, a cross-cutting-gotchas exception, defaults-not-menus, and omit-what's-known — so a future contributor adding a workflow doesn't reintroduce the cluster.
How it fits together
Reference-file migration — each retired skill's SKILL.md body moves (via git mv, tracked as renames) to skills/prisma-next/references/.md, with frontmatter stripped and cross-skill mentions rewritten to reference paths. The queries skill's Postgres/Mongo companions become queries-postgres.md / queries-mongo.md.
A new SKILL.md — authored fresh rather than migrated: one activation description scoped to Prisma 8 signals (@prisma-next/* imports, prisma-next.config.ts, PN-* error codes) that explicitly excludes classic Prisma ORM, a routing table carrying every retired skill's trigger keywords in a Triggers column, and the canonical three-step mental model (edit the contract → the system plans migrations → optionally edit migration.ts).
Upgrade skills hoisted — skills/upgrade/prisma-next-upgrade and skills/extension-author/prisma-next-extension-upgrade move to top-level siblings; their own install instructions and the companion extension-author-tools README are updated to the new --skill command form.
Installer + cleanup — SkillSource gains an explicit skill field; all three entries in DEFAULT_SKILL_SOURCES point at the same skills subpath (only the #ref pinning differs). prisma-next init now deletes the 10 retired per-workflow skill directories from every agent's install root (.agents/skills/, .claude/skills/, .windsurf/skills/) on every run, not just the one legacy stub file it already cleaned up.
Guidelines — skills/DEVELOPING.md gets a new Design principles section (one skill not a cluster, progressive disclosure, length budgets, point-at-the-source-of-truth) plus three additional authoring rules synthesized from a review of published skill-authoring guidance: a cross-cutting-gotchas exception to progressive disclosure, "provide a default, not a menu," and "omit what the agent already knows."
Behavior changes & evidence
prisma-next init installs one skill per explicit --skill instead of a wildcard per subpath — skill-install.ts, tested in skill-install.test.ts.
init now removes retired per-workflow skill directories (e.g. .claude/skills/prisma-next-queries/) from every agent's install root on every run — init.ts, tested in init.test.ts (removes retired per-workflow skill directories left by pre-consolidation installs).
pnpm lint:skills now scans only skills-contrib and skills — the skills/upgrade and skills/extension-author roots no longer exist — validate-skills.mjs, tested in validate-skills.test.mjs.
Reviewer notes
Most of the 65-file diff is git-tracked renames (77–97% similarity) — each retired SKILL.md becomes a reference file with frontmatter stripped and cross-references rewritten; body content is otherwise verbatim. skills/prisma-next/SKILL.md is the one genuinely new file and is worth reading in full.
Verbiage cleanup of the migrated reference files (a few still read "this skill" in first person) is intentionally deferred — this PR is the mechanical consolidation plus the new router; content rewrites are a follow-up.
skills/journey-tests/ still names the retired skill files in its checklists. Relocating it and rewriting its expectations ("prompt X loads reference Y" instead of "prompt X routes to skill Y") is deferred — it's the natural acceptance suite for this migration and deserves its own pass.
Pre-existing, unrelated: test/removed-verb-redirects.test.ts has 8 failing tests on main before this branch; not touched here.
Compatibility / migration / risk
Existing consumer projects that ran prisma-next init before this change have the 10 retired skill directories on disk across three agent install roots. The next prisma-next init run (a plain re-run, not gated on --reinit) deletes them automatically — no separate migration step for consumers who use init.
Projects that installed skills standalone via skills add ... --skill '*' (bypassing init) won't get that automatic cleanup and would need to re-run the install manually. Worth a callout in the next release notes; not addressed in this PR.
Testing performed
pnpm test test/commands/init (packages/1-framework/3-tooling/cli) — 322 passed
pnpm lint / pnpm typecheck (packages/1-framework/3-tooling/cli) — clean (94 pre-existing infos, unrelated to this change)
pnpm lint:skills — all skills pass validation
node --test scripts/validate-skills.test.mjs — 10 passed
Follow-ups
Relocate skills/journey-tests/ and rewrite its expectations against the consolidated routing.
Verbiage cleanup pass on the migrated reference files.
Add the standalone-install migration note (no automatic cleanup outside init) to the next release notes.
Alternatives considered
One giant SKILL.md instead of a reference-file split — rejected because it reintroduces the same "everything competes for the same context budget" problem the consolidation is meant to fix. Progressive disclosure requires the reference layer to load on demand, not up front.
Folding the two upgrade skills into the consolidated skill — rejected because their install ref policy (always main) is structurally different from the version-pinned usage skill; merging them would force one skill to carry two ref policies.
Landing the DEVELOPING.md design-principles rewrite in the same commit as the tree restructure — kept as separate commits so the mechanical move and the design-rationale narrative can be reviewed independently.
Skill update
This PR is the skill update: the usage surface installed by prisma-next init changes from 11 skills to 1 (plus the two separately-versioned upgrade skills), and the install command each consumer project runs changes from a subpath wildcard to an explicit --skill . See At a glance and How it fits together above for the concrete shape; skills/README.md and skills/DEVELOPING.md are updated to describe the new layout and the principles governing it.
Checklist
- All commits are signed off (git commit -s) per the DCO.
- I read CONTRIBUTING.md and the change is scoped to one logical concern (skills consolidation, milestone 1).
- Tests are updated.
- The PR title is in TML-NNNN: form — n/a, no Linear ticket for this change (see Linked issue).</li> <li>The Skill update section above is filled in.</li> </ul> <h3>Summary by CodeRabbit</h3> <h4>New Features</h4> <p>Prisma Next skills are now consolidated into a primary skill with dedicated upgrade skills.</p> <p>Skill installation targets specific capabilities and supports selecting a single agent runtime.</p> <p>Initialization automatically removes retired skill directories.</p> <p>Added upgrade guidance and migration tools for Prisma Next versions 0.8 through 0.17.</p> <h4>Documentation</h4> <p>Updated installation, routing, feedback, and reference guidance for the consolidated skills structure.</p> <p>Added migration instructions for API, contract, storage, hashing, and database changes.</p> <p>Signed-off-by: Tyler Benfield <a href="mailto:[email protected]">[email protected]</a></p>
Curated by the Releasebot team
Releasebot is an aggregator of official release notes from hundreds of software vendors and thousands of sources.
Our editorial process involves the manual review and audit of release notes procured with the help of automated systems.