Skip to content

Allow unknown schema keys across protocol and API (fix #2)#4

Merged
achimala merged 1 commit into
mainfrom
anshu/allow-unknown-keys
Feb 18, 2026
Merged

Allow unknown schema keys across protocol and API (fix #2)#4
achimala merged 1 commit into
mainfrom
anshu/allow-unknown-keys

Conversation

@achimala
Copy link
Copy Markdown
Owner

@achimala achimala commented Feb 18, 2026

Note

Medium Risk
Broadly relaxes Zod validation from strict() to passthrough() across server/web/protocol boundaries, which can hide unexpected payload drift and allow unvalidated data to propagate. Behavior is mostly additive/forward-compatible but affects many request/response validation points.

Overview
Relaxes schema strictness across the stack by switching many Zod schemas from .strict() to .passthrough() so unknown fields are accepted (and typically preserved) for HTTP request bodies, web API responses, and protocol/app-server/IPC/thread payloads.

Updates JSON-RPC parsing to accept extra fields and improves parseJsonRpcIncomingMessage error reporting by validating response vs notification separately and combining Zod issues when neither matches. Protocol docs and tests are updated to reflect/verify acceptance of unknown keys (e.g., model hidden flags and extra top-level response fields).

Written by Cursor Bugbot for commit 0f229c8. This will update automatically on new commits. Configure here.

Summary by CodeRabbit

  • Refactor

    • Updated API validation to accept and preserve additional fields in requests and responses, improving compatibility with future versions and external integrations.
  • Tests

    • Added coverage for hidden flag handling in model list responses.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Feb 18, 2026

📝 Walkthrough

Walkthrough

The pull request systematically replaces strict object validation with passthrough validation across Zod schemas throughout the codebase. This allows unknown fields in inputs and responses to pass through preservation rather than rejection. Affected areas include HTTP request/response schemas, JSON-RPC protocols, and thread/app-server protocols. Some schemas receive explicit type annotations while maintaining runtime behavior changes.

Changes

Cohort / File(s) Summary
Server & HTTP Schemas
apps/server/src/http-schemas.ts
Replaced .strict() with .passthrough() on 8 body schemas (SetModeBodySchema, StartThreadBodySchema, SendMessageBodySchema, SubmitUserInputBodySchema, InterruptBodySchema, TraceStartBodySchema, TraceMarkBodySchema, ReplayBodySchema), allowing unknown properties in request payloads.
Web API Schemas
apps/web/src/lib/api.ts
Converted 7 response schemas from strict to passthrough (HealthResponseSchema, LiveStateResponseSchema, StreamEventsResponseSchema, CreateThreadResponseSchema, TraceStatusSchema, HistoryListSchema, HistoryDetailSchema). LiveStateResponseSchema now has explicit ZodObject type annotation.
JSON-RPC Schemas
packages/codex-api/src/json-rpc.ts
Changed JsonRpcRequestSchema, JsonRpcResponseSchema (inner and outer), and JsonRpcNotificationSchema from strict to passthrough. Refactored parseJsonRpcIncomingMessage to validate sequentially as response then notification, with consolidated error handling.
Protocol AppServer Schemas
packages/codex-protocol/src/app-server.ts
Switched 16 schemas from strict to passthrough (AppServerThreadListItemSchema, AppServerListThreadsResponseSchema, AppServerReadThreadResponseSchema, AppServerModelSchema, AppServerListModelsResponseSchema, collaboration modes, request/response schemas). AppServerReadThreadResponseSchema receives explicit ZodObject type annotation.
Protocol IPC & Thread Schemas
packages/codex-protocol/src/ipc.ts, packages/codex-protocol/src/thread.ts
IPC frame schemas (IpcRequestFrameSchema, IpcResponseFrameSchema, IpcBroadcastFrameSchema, etc.) and 30+ thread-related schemas (ThreadStreamChangeSchema, UserInputRequestSchema, etc.) converted from strict to passthrough. ThreadStreamStateChangedBroadcastSchema and several thread schemas receive explicit ZodObject/ZodUnion type annotations.
Documentation & Tests
packages/codex-protocol/README.md, packages/codex-protocol/test/protocol.test.ts
Updated strictness policy documentation to reflect passthrough default behavior. Added test coverage for hidden flag propagation on app-server model responses and top-level response objects.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

A rabbit hops through fields of Zod,
No longer strict, but free and broad,
Unknown fields now pass on through,
Like clover blessed with morning dew.
Flexibility blooms in every schema—
Less rigid rules, a cleaner lemma! 🐰

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically describes the main change: replacing strict schema validation with passthrough to allow unknown keys across multiple protocol and API files.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch anshu/allow-unknown-keys

Tip

Issue Planner is now in beta. Read the docs and try it out! Share your feedback on Discord.


Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/codex-protocol/README.md (1)

7-7: ⚠️ Potential issue | 🟠 Major

Inconsistency between stated goal and validation policy.

Line 7 states "Fail fast when payloads drift" as a goal, but the new passthrough policy (lines 49-51) allows unknown fields to pass through without failing. This creates a contradiction—passthrough validation is the opposite of failing fast on schema drift.

Consider either:

  1. Updating line 7 to reflect the new permissive validation philosophy (e.g., "Allow forward compatibility while validating known fields"), or
  2. Adding context explaining why passthrough is used despite the fail-fast goal (e.g., "to support protocol evolution while maintaining backward compatibility").

Also applies to: 49-51

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/codex-protocol/README.md` at line 7, The README currently claims
"Fail fast when payloads drift" but the schema validation policy uses
passthrough, which contradicts that goal; either update the headline text to
reflect a permissive/forward-compatible stance (e.g., change "Fail fast when
payloads drift" to "Allow forward compatibility while validating known fields")
or add a brief clarifying sentence near the passthrough policy explaining why
passthrough is chosen (for example: "Passthrough is used to allow protocol
evolution and forward compatibility while still validating known fields"), and
ensure references to "passthrough" and the original headline are consistent so
readers aren't confused by the divergence.
🧹 Nitpick comments (1)
packages/codex-protocol/README.md (1)

49-51: Consider documenting the rationale for passthrough validation.

While the new policy is clearly stated, adding a brief explanation of why passthrough validation was chosen would help users understand the design decision and trade-offs. For example, you might mention protocol evolution, forward compatibility with new server fields, or interoperability requirements.

📝 Example addition
 ## Strictness Policy
 
+- This package uses `.passthrough()` to enable forward compatibility as the protocol evolves.
+- New fields added by the server will not break existing clients.
 - Schemas use `.passthrough()` by default.
 - Unknown fields are allowed and preserved.
 - Required known fields are still validated with exact types.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/codex-protocol/README.md` around lines 49 - 51, Add a short
rationale paragraph next to the existing lines about "Schemas use
`.passthrough()`" explaining why passthrough validation was chosen: mention
protocol evolution and forward-compatibility (servers may add new fields),
interoperability with other clients, and the trade-off that unknown fields are
preserved but will not be type-checked; reference the `.passthrough()` policy
and clarify that required known fields remain strictly validated to reassure
users.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@packages/codex-protocol/README.md`:
- Line 7: The README currently claims "Fail fast when payloads drift" but the
schema validation policy uses passthrough, which contradicts that goal; either
update the headline text to reflect a permissive/forward-compatible stance
(e.g., change "Fail fast when payloads drift" to "Allow forward compatibility
while validating known fields") or add a brief clarifying sentence near the
passthrough policy explaining why passthrough is chosen (for example:
"Passthrough is used to allow protocol evolution and forward compatibility while
still validating known fields"), and ensure references to "passthrough" and the
original headline are consistent so readers aren't confused by the divergence.

---

Nitpick comments:
In `@packages/codex-protocol/README.md`:
- Around line 49-51: Add a short rationale paragraph next to the existing lines
about "Schemas use `.passthrough()`" explaining why passthrough validation was
chosen: mention protocol evolution and forward-compatibility (servers may add
new fields), interoperability with other clients, and the trade-off that unknown
fields are preserved but will not be type-checked; reference the
`.passthrough()` policy and clarify that required known fields remain strictly
validated to reassure users.

@achimala achimala merged commit 9321172 into main Feb 18, 2026
2 checks passed
@achimala achimala deleted the anshu/allow-unknown-keys branch February 18, 2026 19:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant