[PR #2669] fix(config): keybinds should not be required in config schema #10398

Closed
opened 2026-02-16 18:15:02 -05:00 by yindo · 0 comments
Owner

Original Pull Request: https://github.com/anomalyco/opencode/pull/2669

State: closed
Merged: Yes


Problem

The generated JSON schema incorrectly marked all keybind properties as required, even though
they're defined as optional with defaults in the Zod schema
(z.string().optional().default("value")).

Root Cause

Zod's toJSONSchema() defaults to "output" mode, which treats optional().default() fields as
always-defined (hence required) in the generated schema, even though they're optional in the
input config.

Solution

Switch to input mode schema generation using io: "input" parameter, which correctly treats
optional fields with defaults as not required. Also preserve strict validation by ensuring
additionalProperties: false is set for object schemas (this is not done automatically in "input" mode).

Changes

• Modified packages/opencode/script/schema.ts to use io: "input" mode
• Added override to preserve additionalProperties: false for strict validation

Warning

For the future we now have to keep this in mind: When adding new Zod schema fields, avoid these patterns as they don't work well with io: "input" mode for user-facing JSON schema generation:

.transform() - Input/output types will differ
.preprocess() - Preprocessing logic won't be reflected in schema
Complex .refine() or .superRefine() - Custom validation logic may not translate to JSON
schema
Use simple types, .optional(), .default(), .min(), .max(), enums, and unions instead

**Original Pull Request:** https://github.com/anomalyco/opencode/pull/2669 **State:** closed **Merged:** Yes --- ## Problem The generated JSON schema incorrectly marked all keybind properties as required, even though they're defined as optional with defaults in the Zod schema (`z.string().optional().default("value")`). ## Root Cause Zod's `toJSONSchema()` defaults to "output" mode, which treats `optional().default()` fields as always-defined (hence required) in the generated schema, even though they're optional in the input config. ## Solution Switch to input mode schema generation using io: "input" parameter, which correctly treats optional fields with defaults as not required. Also preserve strict validation by ensuring additionalProperties: false is set for object schemas (this is not done automatically in "input" mode). ## Changes • Modified packages/opencode/script/schema.ts to use io: "input" mode • Added override to preserve additionalProperties: false for strict validation ## Warning For the future we now have to keep this in mind: When adding new Zod schema fields, avoid these patterns as they don't work well with io: "input" mode for user-facing JSON schema generation: • ❌ .transform() - Input/output types will differ • ❌ .preprocess() - Preprocessing logic won't be reflected in schema • ❌ Complex .refine() or .superRefine() - Custom validation logic may not translate to JSON schema • ✅ Use simple types, .optional(), .default(), .min(), .max(), enums, and unions instead
yindo added the pull-request label 2026-02-16 18:15:02 -05:00
yindo closed this issue 2026-02-16 18:15:02 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: anomalyco/opencode#10398