Skip to content

fix(jsonschema): root variables object is always a non-nullable "object" - #1528

Merged
asoorm merged 1 commit into
masterfrom
ahmet/eng-9682-jsonschema-root-variables-object-must-always-be-a-non
Jun 8, 2026
Merged

fix(jsonschema): root variables object is always a non-nullable "object"#1528
asoorm merged 1 commit into
masterfrom
ahmet/eng-9682-jsonschema-root-variables-object-must-always-be-a-non

Conversation

@asoorm

@asoorm asoorm commented Jun 5, 2026

Copy link
Copy Markdown
Contributor

Follow-up to #1518. That PR was correct but incomplete and exposed an old defect.

Problem

GetSchema() only forced the root variables object non-nullable when the operation had a required variable:

if len(v.schema.Required) > 0 {
    v.schema.Nullable = false
}

Operations with all-optional variables kept a nullable root. Before #1518 that serialized to {"type":"object","nullable":true} and was harmless (validators ignore the unknown "nullable" keyword). After #1518 it serializes to {"type":["object","null"]}, which strict consumers reject - the MCP go-sdk's AddTool requires the input schema type to be exactly "object" and panics:

panic: AddTool "list_employees": input schema must have type "object" (got [object null])

This breaks the cosmo router engine bump 2.4.2 -> 2.4.3 (wundergraph/cosmo#2925): pkg/mcpserver, protocol and security suites all panic.

Fix

The root variables object is always a concrete object - the container is present or omitted, never the JSON literal null - so set Nullable = false unconditionally in GetSchema(). This is consistent with nested input-object variables, which are already forced non-nullable. Only individual optional fields remain nullable.

Golden tests updated (root ["object","null"] -> "object"); the root_schema_nullable_based_on_required_arguments subtest renamed to root schema is always a non-nullable object.

Tests

go test ./pkg/engine/jsonschema/ passes; gofmt and go vet clean. Verified against the cosmo router via a local replace: pkg/mcpserver no longer panics.

Follow-up

Needs a patch release (2.4.4) and a corresponding engine bump in cosmo#2925.

Fixes ENG-9682

#1518 was correct but incomplete. Switching nullability from the OpenAPI
3.0 "nullable" keyword to the JSON Schema 2020-12 form was right, but it
exposed a latent defect: GetSchema() only forced the root variables object
non-nullable when the operation had a required variable. Operations with
all-optional variables kept a nullable root, which previously serialized to
{"type":"object","nullable":true} and was harmless because validators ignore
the unknown "nullable" keyword. After #1518 it serializes to
{"type":["object","null"]}, which strict consumers reject — the MCP go-sdk's
AddTool requires the input schema type to be exactly "object" and panics
otherwise:

  panic: AddTool "list_employees": input schema must have type "object"
  (got [object null])

This broke the cosmo router engine bump 2.4.2 -> 2.4.3 (pkg/mcpserver,
protocol and security suites).

The root variables object is always a concrete object — the container is
present or omitted, never the JSON literal null — so set Nullable=false
unconditionally in GetSchema(). This is consistent with nested input-object
variables, which are already forced non-nullable. Only individual optional
fields remain nullable.

Update the affected golden tests and rename the
root_schema_nullable_based_on_required_arguments subtest accordingly.

Fixes ENG-9682
@asoorm
asoorm requested a review from a team as a code owner June 5, 2026 21:20

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Claude Code Review

This repository is configured for manual code reviews. Comment @claude review to trigger a review and subscribe this PR to future pushes, or @claude review once for a one-time review.

Tip: disable this comment in your organization's Code Review settings.

@coderabbitai

coderabbitai Bot commented Jun 5, 2026

Copy link
Copy Markdown
Contributor

Too many files changed? Review this PR in Change Stack to see how the pieces fit before you dive in.

Review Change Stack

📝 Walkthrough

Walkthrough

The root variables JSON schema is now unconditionally non-nullable in the GetSchema method, removing prior conditional logic tied to required fields. All corresponding test expectations are updated to verify the root schema type as a strict "object" literal across multiple test scenarios.

Changes

Root Variables Schema Non-Nullable Enforcement

Layer / File(s) Summary
GetSchema non-nullable enforcement
v2/pkg/engine/jsonschema/variables_schema.go
GetSchema now unconditionally sets Nullable=false on the root variables schema, replacing the prior conditional check on len(v.schema.Required). Inline comments clarify that the variables container is either present or omitted and must have type exactly "object" for strict consumers.
Test expectations and validation
v2/pkg/engine/jsonschema/variables_schema_test.go
Test expected JSON outputs across multiple test cases—simple query, nullable/non-nullable fields, optional arguments, top-level fields, and custom scalar types—are updated to expect root schema type: "object" instead of ["object","null"]. Clarifying comments added for optional argument cases and a new test subtest scaffold introduced.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main change: making the root variables object always non-nullable with type "object".
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description check ✅ Passed The pull request description clearly explains the problem (root variables object incorrectly nullable for all-optional-variable operations), the root cause, the fix applied, and test validation.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ahmet/eng-9682-jsonschema-root-variables-object-must-always-be-a-non

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

@asoorm
asoorm merged commit 8327b53 into master Jun 8, 2026
11 checks passed
@asoorm
asoorm deleted the ahmet/eng-9682-jsonschema-root-variables-object-must-always-be-a-non branch June 8, 2026 08:29
ysmolski pushed a commit that referenced this pull request Jun 8, 2026
🤖 I have created a release *beep* *boop*
---


##
[2.4.4](v2.4.3...v2.4.4)
(2026-06-08)


### Bug Fixes

* fallback to abstract name if no __typename was sent
([#1527](#1527))
([2548d5a](2548d5a))
* **jsonschema:** root variables object is always a non-nullable
"object"
([#1528](#1528))
([8327b53](8327b53))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

Co-authored-by: wundergraph-bot[bot] <285992168+wundergraph-bot[bot]@users.noreply.github.com>
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.

2 participants