When upgrading an existing Astro project (using Starlight) to Astro 6 via npx <@&1055234544183287879>/upgrade, the build command (astro build) crashes with the following error during SSR prerendering / chunk generation:
[ERROR] TypeError: z.function(...).optional is not a function
at file:///[...]/dist/server/.prerender/chunks/content.config_xxx.mjs:346:12
Root Cause Analysis
Astro and Starlight currently use the outdated Zod 3 syntax: z.function({...}).optional().
I tracked down two occurrences of this bug inside the currently distributed packages:
- In astro core: File:
packages/astro/src/content/utils.tsInside collectionConfigParser:
// Astro's current code:
createSchema: z.function({...}).optional()
// Should be updated to Zod 4 syntax:
createSchema: z.optional(z.function({...}))
- In
@astrojs/starlight: File:packages/starlight/utils/plugins.tsInside configSetupHookSchema:
// Starlight's current code:
const configSetupHookSchema = z.function({...}).optional();
// Should be updated to Zod 4 syntax:
const configSetupHookSchema = z.optional(z.function({...}));
Steps to Reproduce
- Have an existing Astro project (e.g., using Starlight).
- Run npx <@&1055234544183287879>/upgrade to upgrade the project to Astro 6 (which pulls [email protected]).
- Run npx astro build.
- The build will fail recursively when evaluating the schemas because z.function().optional() is no longer valid in Zod 4.
Expected Behavior
The build should complete successfully. z.optional() should be wrapped around the function schema to ensure compatibility with zod 4.
Environment
Astro version: 6.0.4
Starlight version: 0.38.1
Zod version: 4.3.6
Package Manager: bun (but affects all package managers)
PS: I obviously used AI to understand what I couldn't understand, why the upgrade didn't work. Which led to patch files, which solved the issue, and I asked it to write this post. I fact checked it.