@prisma/orm-postgres 8.0.0-rc.17-dev.27 → 8.0.0-rc.17-dev.29

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@prisma/orm-postgres",
3
- "version": "8.0.0-rc.17-dev.27",
3
+ "version": "8.0.0-rc.17-dev.29",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -10,10 +10,10 @@
10
10
  "skills"
11
11
  ],
12
12
  "dependencies": {
13
- "@prisma/orm-family-sql": "8.0.0-rc.17-dev.27",
14
- "@prisma/orm-framework": "8.0.0-rc.17-dev.27",
15
- "@prisma/orm-target-postgres": "8.0.0-rc.17-dev.27",
16
- "@prisma/orm-toolchain": "8.0.0-rc.17-dev.27",
13
+ "@prisma/orm-family-sql": "8.0.0-rc.17-dev.29",
14
+ "@prisma/orm-framework": "8.0.0-rc.17-dev.29",
15
+ "@prisma/orm-target-postgres": "8.0.0-rc.17-dev.29",
16
+ "@prisma/orm-toolchain": "8.0.0-rc.17-dev.29",
17
17
  "@types/node": "26.1.2",
18
18
  "@types/pg": "8.20.4",
19
19
  "arktype": "^2.2.2",
@@ -22,9 +22,9 @@
22
22
  "tinyglobby": "^0.2.17"
23
23
  },
24
24
  "devDependencies": {
25
- "@internal/postgres": "8.0.0-rc.17-dev.27",
26
- "@repo/tsconfig": "8.0.0-rc.17-dev.27",
27
- "@repo/tsdown": "8.0.0-rc.17-dev.27",
25
+ "@internal/postgres": "8.0.0-rc.17-dev.29",
26
+ "@repo/tsconfig": "8.0.0-rc.17-dev.29",
27
+ "@repo/tsdown": "8.0.0-rc.17-dev.29",
28
28
  "tsdown": "0.22.14",
29
29
  "typescript": "5.9.3"
30
30
  },
@@ -15,7 +15,7 @@ description: >-
15
15
  ORM 7 or earlier (schema.prisma + @prisma/client).
16
16
  metadata:
17
17
  library: '@prisma/orm-postgres'
18
- library_version: '8.0.0-rc.17-dev.27'
18
+ library_version: '8.0.0-rc.17-dev.29'
19
19
  version: '2026-09-12'
20
20
  ---
21
21
 
@@ -86,11 +86,11 @@ The single source of truth: read the envelope, find the row by `code`, follow th
86
86
  | `CONFIG.MISSING_EXTENSION_PACKS` | `contract emit` (e.g. contract uses `pgvector.Vector(...)` but config does not list the pgvector descriptor) | Add the descriptors named in `meta.missingExtensionPacks` to `extensions` in `prisma.config.ts`. See `references/contract.md`. |
87
87
  | `MIGRATION.PLANNING_FAILED` | `db init`, `db update`, `migration plan` | Inspect `meta.conflicts`. Recovery is per-conflict — chain to `references/migrations.md`. When `migration plan` raises it because the planner produced no operations, the conflict's `why` gives the next step (`migration new --from <hash>`, or `db sign` for a database managed with `db update`). |
88
88
  | `CLI.INIT_MISSING_FLAGS` / `CLI.INIT_INVALID_FLAG_VALUE` / `CLI.INIT_REINIT_NEEDS_FORCE` / `CLI.INIT_*` | `prisma orm init` | Re-run with the flags listed in `meta.missingFlags` or `meta.allowed`; a re-init needs `--confirm <directory name>`. `CLI.INIT_INSTALL_FAILED` (exit 4) and `CLI.INIT_EMIT_FAILED` (exit 5) are findings on a completed scaffold — the files are on disk; fix and re-run the named step. |
89
- | `MIGRATION.UNFILLED_PLACEHOLDER` | `node migrations/app/<dir>/migration.ts` (self-emit) or `db migrate` | Edit `migration.ts`, replace the `placeholder("<slot>")` named by `meta.slot` with a real query closure, self-emit. See `references/migrations.md`. |
89
+ | `MIGRATION.UNFILLED_PLACEHOLDER` | `node <package dir>/migration.ts` (self-emit) or `db migrate` | Edit `migration.ts`, replace the `placeholder("<slot>")` named by `meta.slot` with a real query closure, self-emit. See `references/migrations.md`. |
90
90
  | `MIGRATION.FILE_MISSING` | Reading a migration package | Restore from version control or scaffold a fresh package with `migration plan` / `migration new`. |
91
91
  | `MIGRATION.INVALID_DEFAULT_EXPORT` | Loading `migration.ts` | Use `export default class extends Migration<Start, End> { ... }` (or a factory returning `{ operations, targetId, destination }`). See `references/migrations.md`. |
92
92
  | `MIGRATION.DATA_TRANSFORM_CONTRACT_MISMATCH` | Building a data-transform query plan | Pass the same `endContract` reference to both `this.dataTransform(endContract, …)` and the query-builder context. |
93
- | `MIGRATION.HASH_MISMATCH` | Any read of a migration package (`plan`, `list`, `db migrate`) | `ops.json` / `migration.json` were edited without self-emitting. Run `node migrations/app/<dir>/migration.ts` to re-emit. |
93
+ | `MIGRATION.HASH_MISMATCH` | Any read of a migration package (`plan`, `list`, `db migrate`) | `ops.json` / `migration.json` were edited without self-emitting. Run `node <package dir>/migration.ts` to re-emit. |
94
94
  | `CONTRACT.MARKER_MISSING` | `db verify` (`error` diagnostic, exit 4), runtime startup (warning) | DB has no marker yet. Run `prisma db init --db <url>` (baseline empty DB), `db update --db <url>` (apply contract directly), or `db sign --db <url>` if the schema already matches the contract. |
95
95
  | `CONTRACT.MARKER_MISMATCH` | `db verify` (exit 4), runtime startup (warning) | Marker disagrees with contract hash (`meta.expected` / `meta.actual`). Either migrate forward (`db migrate` / `db update`), or — if the DB is correct after a manual fix-up — `db sign`. See `references/migrations.md`. |
96
96
  | `CONTRACT.TARGET_MISMATCH` | `db verify`, runtime startup | Contract target ≠ config target; align them (see `meta.expected` / `meta.actual`). |
@@ -38,7 +38,7 @@ Once the contract changes, you choose how the change reaches the database. This
38
38
  - `ops.json` — canonical operation list. Content-addressed; `migrationHash` is computed over this.
39
39
  - `migration.ts` — TypeScript authoring source, **framework-rendered** by `migration plan` (or `migration new`). You edit specific holes in it (see *Fill a placeholder* below) and re-emit `ops.json` / `migration.json` by running it.
40
40
  - **Contract snapshots.** `migration.ts` imports its bookend contracts from the shared, content-addressed store at `migrations/snapshots/<hex>/contract.json` + `contract.d.ts` (`<hex>` is the contract's 64-hex storage hash) — not from files inside the migration package.
41
- - **Self-emit.** Running `node migrations/app/<dir>/migration.ts` regenerates `ops.json` and `migration.json` from the (possibly edited) TS source. This is the only supported way to update an existing migration package after edits.
41
+ - **Self-emit.** Running `node <package dir>/migration.ts` regenerates `ops.json` and `migration.json` from the (possibly edited) TS source. This is the only supported way to update an existing migration package after edits. `<package dir>` is the directory `migration plan` or `migration new` printed; it sits under the config's `migrations.dir` (by default `migrations/app/<dir>`), so the path depends on that setting. The command works from any directory. Without `--config`, the file uses the config whose migrations directory holds it: the nearest `prisma.config.ts` above it, else the one in the working directory; if neither does, it fails with `CLI.MIGRATION_CONFIG_NOT_FOUND`. If you gave the CLI `--config`, pass the same `--config <path>` to the file.
42
42
  - **`migration.ts` shape.** Framework-rendered. A class `M extends Migration<Start, End>` (from `@internal/postgres/migration` on Postgres, `@prisma/orm-mongo/target/migration` on Mongo — see the framing block below) that assigns the two snapshot imports to `startContractJson` / `endContractJson` (`Start` is `never` and there is no `startContractJson` on a baseline) and has an `operations` getter returning an array of operation values. **On Postgres the operation factories are methods on the base class** (`this.addColumn({...})`, `this.setNotNull({...})`, `this.dataTransform(...)`) taking one options object; free helpers like `col(...)` build the column descriptors they take. **On Mongo they are free factories** (`createIndex(...)`, `dataTransform(...)`) imported beside `Migration`. The file ends with `MigrationCLI.run(import.meta.url, M)` so executing it self-emits.
43
43
  - **`placeholder(slot)`.** A sentinel the planner emits into the rendered `migration.ts` (from the same `.../migration` import as `Migration`) wherever a data transform is needed. Calling `placeholder(...)` at emit time throws `MIGRATION.UNFILLED_PLACEHOLDER` with `meta.slot` naming the hole. The user replaces the `() => placeholder(...)` arrow with a real query-plan closure (Postgres) or fills `dataTransform({ check, run })` sources (Mongo — see *Fill a placeholder*), then self-emits.
44
44
  - **`this.dataTransform(endContract, name, { check, run })`.** The data-transform factory. `check` is a rowset query whose presence-of-any-row signals "work remains"; `run` is one or more mutation queries that perform the backfill. Both are lazy closures returning query-plans built against `endContract`. The runner wraps `check` as `EXISTS(...)` for precheck and `NOT EXISTS(...)` for postcheck, so the same closure asserts both "there is work" and "the work is done".
@@ -70,7 +70,7 @@ Treat the rendered import lines as framework-managed on both targets:
70
70
  | `MIGRATION.FILE_MISSING` | Reading a migration package | `migration.ts`, `migration.json`, or `ops.json` is absent. Recover from version control, re-emit via `migration.ts`, or run `prisma migration new` for a fresh one. |
71
71
  | `MIGRATION.INVALID_DEFAULT_EXPORT` | Loading `migration.ts` | The file's default export is not a `Migration` subclass or factory function. Restore the planner-emitted scaffold from version control or re-run `migration plan` for a clean package. |
72
72
  | `MIGRATION.DATA_TRANSFORM_CONTRACT_MISMATCH` | Building a data-transform query plan | The query builder was instantiated with a contract reference different from the `endContract` passed to `this.dataTransform(...)`. Use the `endContract` imported at module scope for both. |
73
- | `MIGRATION.HASH_MISMATCH` *Migration package is corrupt* | `db migrate` (or any read of the package) | `ops.json` / `migration.json` were edited without self-emitting. Run `node migrations/app/<dir>/migration.ts` to re-emit, then re-run `db migrate`. |
73
+ | `MIGRATION.HASH_MISMATCH` *Migration package is corrupt* | `db migrate` (or any read of the package) | `ops.json` / `migration.json` were edited without self-emitting. Run `node <package dir>/migration.ts` to re-emit, then re-run `db migrate`. |
74
74
  | `CLI.CONSENT_REQUIRED` | `migration plan` / `db update` run with nobody to answer (`--no-interactive`, CI, `--yes`) | The plan would lose data or (on `db update`) widen access. `meta.unanswered` and `nextActions` list each question with the flags that answer it: `--delete <subject>`, `--rename <subject>:<new name>`, `--allow <Model>`. Re-run with the ones you mean. `--confirm` and `--yes` answer none of them. |
75
75
  | `CLI.CONSENT_UNUSED` | `migration plan` / `db update` | Every question was answered, and a `--delete` or `--allow` was left over: a typo, a subject the plan does not touch, or a `--confirm` (which consents to nothing). Fix or drop the flag. A typo next to a question nobody answered is reported as `CLI.CONSENT_REQUIRED` instead, which names the flag that matched nothing. On `db update --dry-run` the same mistake is `MIGRATION.STATEMENT_ANSWERS_NO_QUESTION`. |
76
76
  | `MIGRATION.STATEMENT_DID_NOT_RESOLVE_LOSS` | A rename typed at the data-loss prompt | The plan was made again with the rename and still loses the subject's data. Answer with `delete`, or give a rename whose old name is the subject. |
@@ -349,7 +349,7 @@ export default M;
349
349
  MigrationCLI.run(import.meta.url, M);
350
350
  ```
351
351
 
352
- Self-emit the same way: `node migrations/app/<dir>/migration.ts`.
352
+ Self-emit the same way: `node <package dir>/migration.ts`.
353
353
 
354
354
  ## Workflow — Author a migration by hand
355
355
 
@@ -375,12 +375,13 @@ On Postgres the operations are **methods on the `Migration` base class**, each t
375
375
 
376
376
  **Mongo** factories (from `@prisma/orm-mongo/target/migration`):
377
377
 
378
- - Collections: `createCollection`, `dropCollection`, `validatedCollection`, `setValidation`.
378
+ - Collections: `createCollection`, `dropCollection`, `renameCollection(from, to)` (keeps the documents, indexes and validator), `validatedCollection`, `setValidation`.
379
379
  - Indexes: `createIndex`, `dropIndex`.
380
+ - Document rewrites: `renameField(collection, from, to, { filter? })` and `unsetField(collection, field, { filter? })`, each one `updateMany` that skips validation; `filter` limits them to one variant's documents, such as `{ filter: { type: 'bug' } }`.
380
381
  - Collection options: `collMod`.
381
382
  - Data transforms: `dataTransform(name, { check, run })` (free factory; `check`/`run` use Mongo query-plan shapes).
382
383
 
383
- Self-emit (`node migrations/app/<dir>/migration.ts`) after each edit.
384
+ Self-emit (`node <package dir>/migration.ts`) after each edit.
384
385
 
385
386
  ## Workflow — Inspect the live schema
386
387
 
@@ -455,7 +456,7 @@ pnpm prisma db schema --db $DATABASE_URL --json
455
456
  Fix and re-run `db migrate`:
456
457
 
457
458
  ```bash
458
- node migrations/app/<dir>/migration.ts
459
+ node <package dir>/migration.ts
459
460
  pnpm prisma db migrate --db $DATABASE_URL
460
461
  ```
461
462
 
@@ -466,7 +467,7 @@ If the failure was an out-of-band side-effect that left external systems half-ch
466
467
  The concept: `migrationHash` is content-addressed. A mismatch means `migration.json`'s stored hash disagrees with the hash recomputed from `ops.json` (and metadata). The cause is almost always: someone edited `migration.ts` and forgot to self-emit. The remediation is to self-emit the offending package.
467
468
 
468
469
  ```bash
469
- node migrations/app/<dir>/migration.ts
470
+ node <package dir>/migration.ts
470
471
  pnpm prisma db migrate --db $DATABASE_URL
471
472
  ```
472
473
 
@@ -476,7 +477,7 @@ If self-emit itself fails (e.g. the contract has moved on and the operations no
476
477
 
477
478
  The concept: the planner cannot tell whether a dropped model or field was meant to go, or was renamed. So before `migration plan` writes a package, or `db update` applies, the command asks one question per model, field or storage name an operation would lose data from. `db update` also asks one per model whose rows an operation would open up, such as dropping a row-level-security policy. Each question is answered by a statement:
478
479
 
479
- - `--delete <subject>` lets the data go: `--delete Legacy`, `--delete User.nickname`. A subject no model stores is named by its storage name (`public.audit_log` on Postgres, `audit_log` on SQLite) and can only be deleted.
480
+ - `--delete <subject>` lets the data go: `--delete Legacy`, `--delete User.nickname`. A subject no model stores is named by its storage name (`public.audit_log` on Postgres, `audit_log` on SQLite, `profiles.nickname` for a MongoDB field when `db update` has no snapshot of the origin contract) and can only be deleted. On MongoDB, removing a field from a model is asked about, and `--delete` removes it from every document that holds it.
480
481
  - `--rename <subject>:<new name>` keeps it under a new name: `--rename Profile:User`, or for a field `--rename User.nickname:User.handle` (the new name keeps its model). A field of a renamed model is named through the new name (`--delete User.nickname` after `--rename Profile:User`).
481
482
  - `--allow <Model>` (`db update` only) lets an operation that changes who can read or write the model's rows run: one flag per operation, so a policy drop and disabling row-level security on one model take `--allow User --allow User`.
482
483
 
@@ -499,7 +500,7 @@ In a terminal the command asks each question in turn; type `delete`, `allow`, or
499
500
  6. **Aggregate `check` closure in Postgres `this.dataTransform`.** Returning `count(*)` or `bool_and(...)` breaks the precheck/postcheck contract — both sides resolve to constants. Use a rowset shape: `select('id').where(<violation>).limit(1)`.
500
501
  7. **Two contract references in one migration.** Building a query plan against a different contract than the one passed to `this.dataTransform(endContract, ...)` raises `MIGRATION.DATA_TRANSFORM_CONTRACT_MISMATCH`. Always import `endContract` once at module scope and use the same reference.
501
502
  11. **Calling Postgres operations as free functions.** `addColumn('public', 'user', {...})` does not exist as an import; the operations are `this.addColumn({ schema, table, column })` and friends on the `Migration` base class, with `col(...)` building the column. Only `col`, `rawSql`, `placeholder`, `Migration`, and `MigrationCLI` are imported.
502
- 8. **Renaming a model or field without a statement (Postgres, SQLite).** The planner cannot tell a rename from a drop and a create, so without a statement it plans a destructive drop+add. State the rename on the command line: `migration plan --name <slug> --rename User:Person --rename Person.email:Person.emailAddress`, or the same `--rename` flags on `db update`. A field is named through its model as the new contract names it. The planner then renames the table or column and the constraints and indexes named after it. For a rename statements do not cover, such as a model that keeps its name but changes its `@@map`, hand-edit `migration.ts` with `...this.renameTable(...)` or `...this.renameColumn(...)`, then self-emit.
503
+ 8. **Renaming a model or field without a statement.** The planner cannot tell a rename from a drop and a create, so without a statement it plans a destructive drop+add. State the rename on the command line: `migration plan --name <slug> --rename User:Person --rename Person.email:Person.emailAddress`, or the same `--rename` flags on `db update`. A field is named through its model as the new contract names it. The planner then renames the table or column and the constraints and indexes named after it; on MongoDB it renames the collection, and the field in every document that holds it (only in that variant's documents for a variant's field). On MongoDB a field is named by its stored name: `id @map("_id")` is `User._id`. For a rename statements do not cover, such as a model that keeps its name but changes its `@@map`, hand-edit `migration.ts` with `...this.renameTable(...)` or `...this.renameColumn(...)` (Postgres, SQLite) or `renameCollection(...)` (MongoDB), then self-emit.
503
504
  9. **Planning with no `db` ref and no `--from` in a project that already has migrations.** The origin falls through to the empty database, which would make the plan a full-create migration; `migration plan` refuses with `MIGRATION.PLAN_ORIGIN_UNKNOWN` rather than writing it. Pick the exit that matches your intent — the error lists them, and `references/migration-model.md` § *The trap* explains which to choose.
504
505
  10. **Hand-authoring `migration.ts` from a blank file, or rewriting the rendered import line.** Migration files are framework-rendered — let `prisma migration plan` (or `migration new`) render the package, then edit only the holes the framework leaves for you. On Postgres leave the rendered `@internal/postgres/migration` (or `@internal/sqlite/migration`) import path alone; on Mongo leave `@prisma/orm-mongo/target/migration` as rendered. Add symbols to the existing import line rather than introducing new import paths.
505
506
 
@@ -508,7 +509,7 @@ In a terminal the command asks each question in turn; type `delete`, `allow`, or
508
509
  - **Runtime-apply migrations.** Prisma 8 doesn't apply pending migrations from your app's startup code (the "Drizzle pattern" for serverless / edge). Workaround: run `prisma db migrate` from your deploy pipeline before the app starts. If you need runtime-apply built-in, file a feature request via the `references/feedback.md` skill.
509
510
  - **Seeds-as-first-class.** Prisma 8 doesn't ship a `prisma db seed` equivalent. Workaround: write a TypeScript script that imports your `db` instance and runs your setup queries; invoke it from `package.json`'s scripts. If you need first-class seeding, file a feature request via the `references/feedback.md` skill.
510
511
  - **Migration squashing.** Prisma 8 doesn't squash older migrations into a baseline. They accumulate; for very large histories, manual baseline-and-truncate is the path. If you need built-in squashing, file a feature request via the `references/feedback.md` skill.
511
- - **Renames beyond models and fields, and renames on MongoDB.** `--rename` covers models and fields on Postgres and SQLite. It does not rename enum values, namespaces or value objects, and does not move a model to another namespace. On MongoDB, `--rename` fails with `MIGRATION.PLANNING_FAILED` and plans nothing. A data-loss question about a dropped collection offers only `--delete` and says how to keep the documents by hand; a migration written by `migration plan` still drops the collection, so remove that operation or do not apply it where the collection was renamed. Workaround: follow the error's advice and make the rename by hand in `mongosh` on each database, before a plan made without `--rename` is applied there: `renameCollection` for a model, and for a field turn off the collection's validator, drop each unique index that includes the field, then `updateMany({}, { $rename: ... })`. Applying the plan then creates the new indexes and turns the validator back on. There is no Mongo rename operation to write in `migration.ts`. If you need one of these, file a feature request via the `references/feedback.md` skill.
512
+ - **Renames beyond models and fields.** `--rename` covers models and fields on Postgres, SQLite and MongoDB. It does not rename enum values, namespaces or value objects (on MongoDB, a field inside a value object), and does not move a model to another namespace. On MongoDB it also refuses `_id`, a field whose stored name contains `.` or starts with `$`, and a time-series collection; each refusal (`MIGRATION.PLANNING_FAILED`) says what to do instead. If you need one of these, file a feature request via the `references/feedback.md` skill.
512
513
 
513
514
  ## Graph and history commands
514
515
 
@@ -535,7 +536,7 @@ The CLI collects anonymous usage data by default. To opt out, set `PRISMA_DISABL
535
536
  - [ ] For `migration plan`: ran `migration show <dir>` to review before `db migrate`.
536
537
  - [ ] Filled every `placeholder(...)` in `migration.ts` (if any), built against `endContract`.
537
538
  - [ ] `check` closures are rowset queries, not scalar aggregates.
538
- - [ ] Self-emitted (`node migrations/app/<dir>/migration.ts`) after editing the TS.
539
+ - [ ] Self-emitted (`node <package dir>/migration.ts`) after editing the TS.
539
540
  - [ ] Ran `db migrate` (or `db update`) and saw it complete.
540
541
  - [ ] Used `db verify` only when diagnosing drift — not as a routine post-apply step.
541
542
  - [ ] Did NOT use `db update` against a shared or production database.
@@ -820,7 +820,7 @@ The `migration.ts` that `migration plan` writes for a new SQLite table now gives
820
820
 
821
821
  A migration operation that changes an existing default on PostgreSQL checked afterwards only that the column has a default. The old default passes that check, and the runner skips an operation whose check already passes, so the default stayed as it was and verification then failed with `MIGRATION.SCHEMA_VERIFY_FAILED`. Such an operation now has no check afterwards and always runs; setting a default twice changes nothing.
822
822
 
823
- A migration package an earlier version planned keeps the old check in `ops.json`. If one changes a default and you have not applied it, write its `ops.json` again before you apply it with `prisma db migrate`. Either delete the package and run `prisma migration plan` again, or rewrite its `setDefault` call in `migration.ts` to the form [`migration-ts-column-defaults`](#migration-ts-column-defaults) shows and then run the file (`node migration.ts`). Run unchanged, the file stops with `MIGRATION.OPERATION_OPTION_REMOVED`, because its `setDefault` still passes `defaultSql`. `db update` plans again each time, so it needs nothing.
823
+ A migration package an earlier version planned keeps the old check in `ops.json`. If one changes a default and you have not applied it, write its `ops.json` again before you apply it with `prisma db migrate`. Either delete the package and run `prisma migration plan` again, or rewrite its `setDefault` call in `migration.ts` to the form [`migration-ts-column-defaults`](#migration-ts-column-defaults) shows and then run the file with node from the directory that holds `prisma.config.ts` (`node <path to the package>/migration.ts`). Run unchanged, the file stops with `MIGRATION.OPERATION_OPTION_REMOVED`, because its `setDefault` still passes `defaultSql`. `db update` plans again each time, so it needs nothing.
824
824
 
825
825
  ## `cli-error-from-caught`
826
826
 
@@ -585,7 +585,7 @@ The planner and the migration factories now class an operation as `destructive`
585
585
 
586
586
  A migration that is already applied needs nothing: `prisma db migrate` applies its `ops.json` as written, and the database ledger records the migration by its hash.
587
587
 
588
- For each migration package that no database has applied yet and whose `migration.ts` calls `setNotNull` (Postgres), or `dropIndex`, `setValidation` or `collMod` without an `operationClass` (MongoDB), run its `migration.ts` again (`node migration.ts`) so that `ops.json` records the new class. This rewrites `ops.json` and the `migrationHash` in `migration.json`. Do not run it again for a package a database has applied: its new hash would no longer match the hash the database's ledger recorded for it.
588
+ For each migration package that no database has applied yet and whose `migration.ts` calls `setNotNull` (Postgres), or `dropIndex`, `setValidation` or `collMod` without an `operationClass` (MongoDB), run its `migration.ts` again with node from the directory that holds `prisma.config.ts` (`node <path to the package>/migration.ts`) so that `ops.json` records the new class. This rewrites `ops.json` and the `migrationHash` in `migration.json`. Do not run it again for a package a database has applied: its new hash would no longer match the hash the database's ledger recorded for it.
589
589
 
590
590
  ## `migration-plan-refuses-data-loss`
591
591