fix(framework-components): call descriptor.factory as a method - #30222
Conversation
materializeCodec evaluated descriptor.factory to a bare value before calling it, so `this` was undefined inside the factory. Every codec built as `new XCodec(this)` therefore received `descriptor === undefined`, and `codec.id` — which reads `this.descriptor.codecId` — threw. The only readers of `codec.id` are the decode and encode failure wrappers, so the fault surfaced as `Cannot read properties of undefined (reading 'codecId')` from inside the code that builds the "failed to decode column X.Y" message, replacing a diagnostic that names the column with one that names nothing. Calling factory as a method restores the receiver. The blindCast is no longer needed: AnyCodecDescriptor is CodecDescriptor<any>, so the validated params pass without narrowing. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UcqoY3CKfnubdZt5YQk2Rq Signed-off-by: Steven McClankerton <tatarintsev@prisma.io>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yml Review profile: CHILL Plan: Team Run ID: 📒 Files selected for processing (2)
Included review availability: Your plan provides up to 10 included reviews per hour; 9 remain after this review. 📝 WalkthroughWalkthrough
ChangesCodec materialization
Estimated code review effort: 2 (Simple) | ~10 minutes Merge Risk: ⚪ Minimal · up to Codec descriptor factories now retain their descriptor receiver during materialization, fixing class-based codec construction while preserving parameter and instance-context forwarding. Coverage includes fixed and parameterized codecs with encode/decode behavior, and no current merge-blocking risk remains. Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
Comment |
@prisma/orm-extension-arktype-json
@prisma/orm-extension-middleware-cache
@prisma/orm-extension-paradedb
@prisma/orm-extension-pgvector
@prisma/orm-extension-postgis
@prisma/orm-extension-supabase
@prisma/orm-family-mongo
@prisma/orm-family-sql
@prisma/orm-framework
@prisma/orm-mongo
@prisma/orm-postgres
@prisma/orm-sqlite
@prisma/orm-target-mongo
@prisma/orm-target-postgres
@prisma/orm-target-sqlite
@prisma/orm-toolchain
commit: |
size-limit report 📦
|
Summary
materializeCodecevaluateddescriptor.factoryto a bare value before calling it, sothiswasundefinedinside the factory. Every codec built asnew XCodec(this)— the standard pattern for class-based codecs — receiveddescriptor === undefined.CodecImpl.get id()isthis.descriptor.codecId, socodec.idthrew on every such codec.Why it went unnoticed
idis read almost nowhere: the decode and encode failure wrappers read it to build their message, and little else does. So the fault only surfaced on an already-failing path — and when it did, it replaced a diagnostic that names the column with one that names nothing:The wrapper's real message —
Failed to decode column <table>.<column> with codec '<id>'— already existed and never got the chance to render. Bothdecoding.tsandencoding.tswere affected.The change
The
blindCastis not needed once the call is a method call:AnyCodecDescriptorisCodecDescriptor<any>, so the validated params pass without narrowing. Net one fewer cast against the ratchet.Blast radius
this.descriptoris dereferenced at four production sites (codec.ts:73, the postgres and sqlite codec descriptors). None branches or memoises on it, so nothing depended on theundefined.Closure-style factories were already correct —
PostgresCodecDescriptorAdapterassignsthis.factory = (params) => descriptor.factory(params), an arrow that forwards regardless of receiver. So adapted extension descriptors (pgvector, postgis, arktype-json) were unaffected; only directly-declaredCodecDescriptorImplsubclasses were broken.Testing
materialize-codec.test.tscovers a non-parameterized and a parameterized descriptor whose factories usenew XCodec(this), and assertscodec.id. Verified load-bearing: againstmain's version 2 of the 3 cases fail with the exactCannot read properties of undefined (reading 'codecId')above.@internal/framework-components: 54 files, 628 tests@internal/sql-runtime343,@internal/target-postgres1596,@internal/adapter-postgres867 + 3 expected-failpnpm typecheck: 166/166; package lint cleanProvenance
Salvaged from #30195, which was closed. That PR paired this fix with an interim
::text[]projection cast for enum-array decoding; the cast is superseded by target-owned list framing, but this defect is unrelated to framing and is worth landing on its own.🤖 Generated with Claude Code
https://claude.ai/code/session_01UcqoY3CKfnubdZt5YQk2Rq
Summary by CodeRabbit
Bug Fixes
Tests