Skip to content

Namespace import object is not materialised: Object.keys(ns) is empty and some members (zod's z.coerce) are undefined, while others work #8904

Description

@proggeramlug

perry 0.5.1220, macOS arm64, zod ^4.0.0 listed in both perry.compilePackages and perry.allow.compilePackages.

A namespace-style export object comes out partially materialised. Direct access to some members works; Object.keys() on it returns nothing at all; and at least one member (z.coerce) is undefined even though it is accessed statically.

Repro

import { z } from "zod";

function main(): void {
  console.log("typeof z            :", typeof z);
  console.log("typeof z.object     :", typeof z.object);
  console.log("typeof z.string     :", typeof z.string);
  console.log("typeof z.coerce     :", typeof (z as unknown as { coerce?: unknown }).coerce);
  const keys = Object.keys(z as unknown as Record<string, unknown>);
  console.log("z key count         :", keys.length);
  console.log("'coerce' in z       :", "coerce" in (z as unknown as object));
  console.log("descriptor          :", Object.getOwnPropertyDescriptor(z as unknown as object, "coerce"));
}
main();
perry 0.5.1220 node 26
typeof z object object
typeof z.object function function
typeof z.string function function
typeof z.coerce undefined object
Object.keys(z).length 0 238
"coerce" in z false true
getOwnPropertyDescriptor(z, "coerce") undefined {value, writable, enumerable, configurable}

Where it bites

const Nested = z.object({ rows: z.array(z.object({ n: z.coerce.number() })).min(1) });

TypeError: Cannot read properties of undefined (reading 'number')

That is a plain, statically-visible z.coerce.number() — not dynamic access — so whatever decides which members to retain does not appear to follow nested member expressions through the namespace.

The Object.keys(z).length === 0 result is the part I would point at first: the object exists and answers some property reads, but has no own enumerable properties at all. Any library that iterates its own namespace (or does "x" in ns feature detection) would take a wrong branch silently rather than throwing.

Why it took a while to see

The failure is late and looks like a library bug: six earlier assertions in the same file pass — z.object, z.array, z.string, discriminated unions, .transform, z.enum — so zod is clearly compiled and working. Only coerce is missing, and the resulting TypeError names number, which points at the wrong place.

Environment

  • perry 0.5.1220 (current latest release), macOS arm64
  • compiled with PERRY_NO_AUTO_OPTIMIZE=1 (prebuilt stdlib)
  • zod ^4.0.0, listed in perry.compilePackages and perry.allow.compilePackages

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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