Skip to content

bundled zod broken: optional().parse(undefined) throws, subclass identity collapses to ZodType — Next.js standalone boot blocker (config-schema init) #6530

Description

@proggeramlug

Summary

Next.js's bundled zod (next/dist/compiled/zod/index.cjs) breaks under perry in several related ways; the smallest repro is a one-liner. This is the current gscmaster/Next.js standalone boot blocker (layer 3, behind #6522 and #6523/#6527 which are now merged): next/dist/server/config-schema.js init dies with TypeError: Cannot read properties of undefined (reading 'description').

Repros (driver requires a local copy of next/dist/compiled/zod/index.cjs)

const z = require("./zod-index.cjs").z;

// 1. SMALLEST: parse an optional with undefined input
z.string().optional().parse(undefined);
// perry: TypeError: Cannot read properties of undefined (reading 'errorMap')
// node:  returns undefined

// 2. record with an object value type containing an .optional() field
z.record(z.string(), z.object({ p: z.string(), q: z.boolean().optional() }))
  .parse({ a: { p: "x" } });
// perry: TypeError: Cannot read properties of undefined (reading '_getType')
// node:  { a: { p: "x" } }

// 3. subclass identity collapses to the base class
z.string().constructor.name   // perry: "ZodType"   node: "ZodString"
z.object({}).constructor.name // perry: "ZodType"   node: "ZodObject"

Notably z.record(z.string(), z.boolean()).parse(...), z.object({p:z.string()}).parse(...), and z.array(z.any()).optional() (creation only) all work — the failures need the optional-parse path / richer schemas.

Boot-time manifestation (gscmaster / any Next 16 standalone app)

next/dist/server/config-schema.js init → ZodRecord.create → a field-by-name read walks the proto chain into ZodType's get description() with a receiver whose _def is undefined → uncaught TypeError → server dies before Ready. lldb stack (debug-symbol build, b js_throw_type_error_property_access):

js_throw_type_error_property_access
← perry_method_…zod_index_cjs__ZodType____get_get_description
← get_field_by_name_object_tail ← js_object_get_field_by_name
← resolve_proto_chain_field_inner ← js_object_get_field_by_name_f64
← …zod_index_cjs__118 ← __537 ← perry_static_…ZodRecord__c10712__create
← js_class_static_method_call ← … ← NEXT_server_config_schema_js__init_body ← main

Suspected bug family

The subclass-identity collapse (repro 3) suggests the bundled zod's class-hierarchy shape (class ZodString extends ZodType + statics assigned after the class + namespace/getter exports) constructs instances with base-class identity — the "native-base subclassing / subclass statics" family (#6232, myairank walls). The get description proto-chain hit with a foreign/incomplete receiver and the errorMap/_getType undefined reads look like downstream symptoms of instances missing their subclass construction.

Verified on main @ 23f1f35 (includes #6522, #6527, #6494, #6506).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions