Skip to content

fix: preserve falsy literal default values (false, 0, '') during contract canonicalization#804

Open
prisma-gremlin[bot] wants to merge 1 commit into
mainfrom
fix/falsy-literal-default-emit
Open

fix: preserve falsy literal default values (false, 0, '') during contract canonicalization#804
prisma-gremlin[bot] wants to merge 1 commit into
mainfrom
fix/falsy-literal-default-emit

Conversation

@prisma-gremlin

@prisma-gremlin prisma-gremlin Bot commented Jun 10, 2026

Copy link
Copy Markdown

Problem

@default(false) loses its value on emit, producing {"kind":"literal"} with no value property. This fails contract validation with PN-CLI-4003. @default(true) works correctly because true is not treated as a default-omission candidate.

Root Cause

In canonicalization.ts, the omitDefaults walk uses isDefaultValue() to identify values that should be stripped from the JSON envelope. isDefaultValue(false) returns true — which is correct for fields like nullable: false and generated: false that are indeed defaults. However, when the walk reaches value: false inside default: { kind: "literal", value: false }, the same logic strips the value key, producing the invalid { kind: "literal" }.

Fix

Add an isDefaultLiteralValue guard in omitDefaults: when key === "value" and the parent path element is "default", skip the default-omission logic so that falsy values (false, 0, "") inside literal defaults are always preserved.

Changed files:

  • packages/1-framework/0-foundation/contract/src/canonicalization.ts — add isDefaultLiteralValue guard
  • packages/1-framework/0-foundation/contract/test/canonicalization.test.ts — add tests for value: false, value: 0, value: ""
  • packages/1-framework/3-tooling/emitter/test/canonicalization.test.ts — add tests for value: false, value: 0

Summary by CodeRabbit

Release Notes

  • Bug Fixes

    • Corrected handling of default literal values to prevent falsy values (false, 0, empty string) from being incorrectly removed during canonicalization operations.
  • Tests

    • Added comprehensive test coverage verifying that falsy literal default values are properly preserved in column definitions after canonicalization.

…ract canonicalization

The omitDefaults walk in canonicalization.ts treats false as a default
value to strip (for nullable:false, generated:false, etc.). This caused
default: { kind: 'literal', value: false } to lose its value key during
emit, producing { kind: 'literal' } without a value property — which
fails contract validation with PN-CLI-4003.

Add isDefaultLiteralValue guard: when key === 'value' and the parent
path element is 'default', skip the default-omission logic so that
falsy values (false, 0, '') inside literal defaults are always
preserved.
@prisma-gremlin prisma-gremlin Bot requested a review from a team as a code owner June 10, 2026 16:55
@coderabbitai

coderabbitai Bot commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

Run ID: 9f34b2d6-588f-4128-812d-a273be1574c6

📥 Commits

Reviewing files that changed from the base of the PR and between dc0f923 and 6c3bde3.

📒 Files selected for processing (3)
  • packages/1-framework/0-foundation/contract/src/canonicalization.ts
  • packages/1-framework/0-foundation/contract/test/canonicalization.test.ts
  • packages/1-framework/3-tooling/emitter/test/canonicalization.test.ts

📝 Walkthrough

Walkthrough

The PR fixes canonicalization to preserve falsy literal default values on column definitions. A new predicate detects when the current key is value under a default path segment, then the omission conditional excludes this case to prevent stripping. Test coverage verifies the fix for false, 0, and empty-string literals across foundation and emitter test suites.

Changes

Preserve literal default values in canonicalization

Layer / File(s) Summary
Core implementation and foundation test coverage
packages/1-framework/0-foundation/contract/src/canonicalization.ts, packages/1-framework/0-foundation/contract/test/canonicalization.test.ts
The omitDefaults function adds a predicate isDefaultLiteralValue to detect the value key under a default path segment, then excludes this case from the omission conditional to prevent stripping. Foundation contract tests verify literal defaults for false, 0, and '' are preserved exactly.
Emitter canonicalization test coverage
packages/1-framework/3-tooling/emitter/test/canonicalization.test.ts
Emitter test suite adds parallel coverage verifying that falsy literal column defaults (false and 0) are preserved exactly in the canonicalized output.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Poem

🐰 A rabbit hops through defaults clear,
Falsy values, never fear!
Zero, false, and empty strings—
Preserved through canonicalization's wings!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: fixing preservation of falsy literal default values during canonicalization, which directly addresses the core issue outlined in the PR objectives.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/falsy-literal-default-emit

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

@pkg-pr-new

pkg-pr-new Bot commented Jun 10, 2026

Copy link
Copy Markdown

Open in StackBlitz

@prisma-next/extension-author-tools

npm i https://pkg.pr.new/@prisma-next/extension-author-tools@804

@prisma-next/mongo-runtime

npm i https://pkg.pr.new/@prisma-next/mongo-runtime@804

@prisma-next/family-mongo

npm i https://pkg.pr.new/@prisma-next/family-mongo@804

@prisma-next/sql-runtime

npm i https://pkg.pr.new/@prisma-next/sql-runtime@804

@prisma-next/family-sql

npm i https://pkg.pr.new/@prisma-next/family-sql@804

@prisma-next/extension-arktype-json

npm i https://pkg.pr.new/@prisma-next/extension-arktype-json@804

@prisma-next/middleware-cache

npm i https://pkg.pr.new/@prisma-next/middleware-cache@804

@prisma-next/mongo

npm i https://pkg.pr.new/@prisma-next/mongo@804

@prisma-next/extension-paradedb

npm i https://pkg.pr.new/@prisma-next/extension-paradedb@804

@prisma-next/extension-pgvector

npm i https://pkg.pr.new/@prisma-next/extension-pgvector@804

@prisma-next/extension-postgis

npm i https://pkg.pr.new/@prisma-next/extension-postgis@804

@prisma-next/postgres

npm i https://pkg.pr.new/@prisma-next/postgres@804

@prisma-next/sql-orm-client

npm i https://pkg.pr.new/@prisma-next/sql-orm-client@804

@prisma-next/sqlite

npm i https://pkg.pr.new/@prisma-next/sqlite@804

@prisma-next/extension-supabase

npm i https://pkg.pr.new/@prisma-next/extension-supabase@804

@prisma-next/target-mongo

npm i https://pkg.pr.new/@prisma-next/target-mongo@804

@prisma-next/adapter-mongo

npm i https://pkg.pr.new/@prisma-next/adapter-mongo@804

@prisma-next/driver-mongo

npm i https://pkg.pr.new/@prisma-next/driver-mongo@804

@prisma-next/contract

npm i https://pkg.pr.new/@prisma-next/contract@804

@prisma-next/utils

npm i https://pkg.pr.new/@prisma-next/utils@804

@prisma-next/config

npm i https://pkg.pr.new/@prisma-next/config@804

@prisma-next/errors

npm i https://pkg.pr.new/@prisma-next/errors@804

@prisma-next/framework-components

npm i https://pkg.pr.new/@prisma-next/framework-components@804

@prisma-next/operations

npm i https://pkg.pr.new/@prisma-next/operations@804

@prisma-next/ts-render

npm i https://pkg.pr.new/@prisma-next/ts-render@804

@prisma-next/contract-authoring

npm i https://pkg.pr.new/@prisma-next/contract-authoring@804

@prisma-next/ids

npm i https://pkg.pr.new/@prisma-next/ids@804

@prisma-next/psl-parser

npm i https://pkg.pr.new/@prisma-next/psl-parser@804

@prisma-next/psl-printer

npm i https://pkg.pr.new/@prisma-next/psl-printer@804

@prisma-next/cli

npm i https://pkg.pr.new/@prisma-next/cli@804

@prisma-next/cli-telemetry

npm i https://pkg.pr.new/@prisma-next/cli-telemetry@804

@prisma-next/emitter

npm i https://pkg.pr.new/@prisma-next/emitter@804

@prisma-next/migration-tools

npm i https://pkg.pr.new/@prisma-next/migration-tools@804

prisma-next

npm i https://pkg.pr.new/prisma-next@804

@prisma-next/vite-plugin-contract-emit

npm i https://pkg.pr.new/@prisma-next/vite-plugin-contract-emit@804

@prisma-next/mongo-codec

npm i https://pkg.pr.new/@prisma-next/mongo-codec@804

@prisma-next/mongo-contract

npm i https://pkg.pr.new/@prisma-next/mongo-contract@804

@prisma-next/mongo-value

npm i https://pkg.pr.new/@prisma-next/mongo-value@804

@prisma-next/mongo-contract-psl

npm i https://pkg.pr.new/@prisma-next/mongo-contract-psl@804

@prisma-next/mongo-contract-ts

npm i https://pkg.pr.new/@prisma-next/mongo-contract-ts@804

@prisma-next/mongo-emitter

npm i https://pkg.pr.new/@prisma-next/mongo-emitter@804

@prisma-next/mongo-schema-ir

npm i https://pkg.pr.new/@prisma-next/mongo-schema-ir@804

@prisma-next/mongo-query-ast

npm i https://pkg.pr.new/@prisma-next/mongo-query-ast@804

@prisma-next/mongo-orm

npm i https://pkg.pr.new/@prisma-next/mongo-orm@804

@prisma-next/mongo-query-builder

npm i https://pkg.pr.new/@prisma-next/mongo-query-builder@804

@prisma-next/mongo-lowering

npm i https://pkg.pr.new/@prisma-next/mongo-lowering@804

@prisma-next/mongo-wire

npm i https://pkg.pr.new/@prisma-next/mongo-wire@804

@prisma-next/sql-contract

npm i https://pkg.pr.new/@prisma-next/sql-contract@804

@prisma-next/sql-errors

npm i https://pkg.pr.new/@prisma-next/sql-errors@804

@prisma-next/sql-operations

npm i https://pkg.pr.new/@prisma-next/sql-operations@804

@prisma-next/sql-schema-ir

npm i https://pkg.pr.new/@prisma-next/sql-schema-ir@804

@prisma-next/sql-contract-psl

npm i https://pkg.pr.new/@prisma-next/sql-contract-psl@804

@prisma-next/sql-contract-ts

npm i https://pkg.pr.new/@prisma-next/sql-contract-ts@804

@prisma-next/sql-contract-emitter

npm i https://pkg.pr.new/@prisma-next/sql-contract-emitter@804

@prisma-next/sql-lane-query-builder

npm i https://pkg.pr.new/@prisma-next/sql-lane-query-builder@804

@prisma-next/sql-relational-core

npm i https://pkg.pr.new/@prisma-next/sql-relational-core@804

@prisma-next/sql-builder

npm i https://pkg.pr.new/@prisma-next/sql-builder@804

@prisma-next/target-postgres

npm i https://pkg.pr.new/@prisma-next/target-postgres@804

@prisma-next/target-sqlite

npm i https://pkg.pr.new/@prisma-next/target-sqlite@804

@prisma-next/adapter-postgres

npm i https://pkg.pr.new/@prisma-next/adapter-postgres@804

@prisma-next/adapter-sqlite

npm i https://pkg.pr.new/@prisma-next/adapter-sqlite@804

@prisma-next/driver-postgres

npm i https://pkg.pr.new/@prisma-next/driver-postgres@804

@prisma-next/driver-sqlite

npm i https://pkg.pr.new/@prisma-next/driver-sqlite@804

commit: 6c3bde3

@github-actions

Copy link
Copy Markdown

size-limit report 📦

Path Size
postgres / no-emit 152.02 KB (+0.02% 🔺)
postgres / emit 120.34 KB (0%)
mongo / no-emit 76.7 KB (+0.04% 🔺)
mongo / emit 70.96 KB (0%)
cf-worker / no-emit 180.97 KB (+0.02% 🔺)
cf-worker / emit 145.99 KB (0%)

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.

0 participants