fix: revert .optional() to .default([]) and strip empty evo arrays on write#1074
fix: revert .optional() to .default([]) and strip empty evo arrays on write#1074
Conversation
… write The .optional() change from #1073 breaks Zod JSON Schema generation ("Undefined cannot be represented in JSON Schema"). Revert to .default([]) so schema generation and parsing work, but strip empty configBundles/abTests/httpGateways in writeProjectSpec before writing to disk so preview features don't pollute agentcore.json.
agentcore-cli-automation
left a comment
There was a problem hiding this comment.
The empty-array stripping in writeProjectSpec won't actually keep these fields out of agentcore.json. The stripping runs on the input data, but validateAndWrite then calls schema.safeParse(data) and writes result.data — and because the schema uses .default([]), Zod re-populates the stripped fields with empty arrays on parse. The written JSON will still contain "configBundles": [], "abTests": [], "httpGateways": [].
Quick trace with the agentcore create path:
createDefaultProjectSpec()returns an object withoutconfigBundles/abTests/httpGateways(seesrc/cli/project.ts).writeProjectSpec(spec)— the threecleaned.xxx?.length === 0checks are all false (the fields areundefined, not empty arrays), so nothing is deleted.validateAndWrite→AgentCoreProjectSpecSchema.safeParse(cleaned)applies.default([])for each of the three fields.JSON.stringify(result.data, null, 2)writesconfigBundles: [],abTests: [],httpGateways: []to disk.
So the second objective in the PR description ("writeProjectSpec: Strip empty arrays... so preview features don't appear in agentcore.json for users who haven't opted in") isn't met as written.
A few options to actually achieve that:
-
Strip after validation. Parse with the schema, then delete the empty arrays from
result.databefore stringifying. This would likely require splitting the logic out of the genericvalidateAndWrite(e.g., do a manual parse + post-process + write inwriteProjectSpec), or adding an optional post-validate hook. -
Use a separate write schema that keeps the fields
.optional()(no default) for serialization, while the read/runtime schema keeps.default([]). The schema used bygenerate-schema.mjs(the one that was breaking) can stay.default([]); the write path uses the optional variant. -
Keep
.optional()everywhere (the #1073 approach) and fix the JSON-Schema generation failure differently. Sincegenerate-schema.mjsalready strips defaults fromrequired, the real blocker wasz.toJSONSchemathrowing onundefined. That can typically be handled by wrapping the optional arrays with.default([])only at JSON-schema-generation time, or by pre-processing the schema before callingz.toJSONSchema.
Option 1 is probably the smallest change. Either way, the current PR doesn't produce the intended agentcore.json output — worth adding a test that reads the file after agentcore create and asserts these keys are absent, which would catch this.
Coverage Report
|
Summary
Fixes the JSON Schema generation failure introduced by #1073. The
.optional()change causes Zod v4'stoJsonSchema()to throw "Undefined cannot be represented in JSON Schema" during the release workflow.Approach
configBundles,abTests,httpGatewaysback to.default([])so JSON Schema generation and Zod parsing work correctlyagentcore.jsonfor users who haven't opted inThis gives us both: correct schema generation AND clean user files.
Test plan
npm run typecheckpassesnpm run generate-schemasucceeds (no "Undefined cannot be represented" error)agentcore createdoes not write configBundles/abTests/httpGatewaysagentcore add config-bundlecorrectly writes configBundles