Skip to content

Zod v4 schema detection can fail when root zod resolves without toJSONSchema #1845

@rowan-aldean-verifast

Description

@rowan-aldean-verifast

Summary

We are seeing a runtime failure in Stagehand 3.1.0 when stagehand.extract() receives a Zod v4-style schema object, but Stagehand's own root zod import does not expose z.toJSONSchema().

The failure comes from dist/esm/lib/v3/zodCompat.js:

import { z } from "zod";
import zodToJsonSchema from "zod-to-json-schema";
export const isZod4Schema = (schema) => typeof schema._zod !== "undefined";
export function toJsonSchema(schema) {
  if (!isZod4Schema(schema)) {
    return zodToJsonSchema(schema);
  }
  const zodWithJsonSchema = z;
  if (zodWithJsonSchema.toJSONSchema) {
    return zodWithJsonSchema.toJSONSchema(schema);
  }
  throw new Error("Zod v4 toJSONSchema method not found");
}

In our deployment artifact, this throws:

Error: Zod v4 toJSONSchema method not found

Why this is surprising

Stagehand declares support for:

  • zod ^3.25.76 || ^4.2.0

But there is a runtime shape where:

  • the schema object looks like Zod v4 (_zod exists)
  • Stagehand's own root zod import does not expose toJSONSchema

That means Stagehand detects the schema as v4, but then assumes its own imported z also has the v4 root API surface.

Reproduction shape

This is enough to reproduce the failure in our built output:

import { z } from './node_modules/zod/v4/index.js';
import { toJsonSchema } from './node_modules/@browserbasehq/stagehand/dist/esm/lib/v3/zodCompat.js';

toJsonSchema(z.object({ ok: z.boolean() }));

This throws:

Error: Zod v4 toJSONSchema method not found

What seems to be happening

In our case, the deploy artifact ends up with a transitional zod@3.25.76 package at the root, where:

  • import { z } from "zod" does not provide toJSONSchema
  • import { z } from "zod/v4" does provide toJSONSchema

So the mismatch is:

  • Stagehand gets a v4 schema object
  • Stagehand imports root zod
  • root zod is not the v4 root surface Stagehand expects

Related upstream packaging issue

We also opened an issue with the Mastra team because the mismatch appears during their generated build output packaging:

That said, this still seems like Stagehand could be more defensive here, since downstream build systems may legitimately hand it a v4 schema object while root zod resolves differently.

Questions

  1. Is this a known issue?
  2. Do you recommend always using zod/v3 schemas with stagehand.extract() as the safest option in production?
  3. Would you consider making the v4 path more defensive, for example by:
    • importing from zod/v4 when available, or
    • falling back more gracefully instead of throwing when schema is v4-shaped but root z lacks toJSONSchema?
  4. Is there a canonical way you want consumers to avoid this class of drift in bundled/deployed environments?

Happy to provide more detail if useful.

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