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

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions