Skip to content

fix: serialize ElicitRequest mode discriminator only once#1045

Open
aditya-786 wants to merge 1 commit into
modelcontextprotocol:mainfrom
aditya-786:fix/elicit-request-duplicate-mode
Open

fix: serialize ElicitRequest mode discriminator only once#1045
aditya-786 wants to merge 1 commit into
modelcontextprotocol:mainfrom
aditya-786:fix/elicit-request-duplicate-mode

Conversation

@aditya-786

Copy link
Copy Markdown

Problem

ElicitRequest declares its subtype discriminator with @JsonTypeInfo(use = Id.NAME, include = As.PROPERTY, property = "mode"), so Jackson already writes the mode property when serializing an ElicitFormRequest or ElicitUrlRequest. Both subtypes also annotate their overridden mode() accessor with @JsonProperty("mode"), so mode is written a second time, producing a duplicate JSON key:

{"mode":"form","message":"msg","requestedSchema":{"type":"object"},"mode":"form"}
{"mode":"url","message":"msg","url":"https://example.com","elicitationId":"eid","mode":"url"}

Duplicate object keys violate RFC 8259 and can be rejected by strict client-side parsers.

This is the same defect already fixed on the parallel Content hierarchy, where Content.type() is marked @JsonIgnore and ContentJsonTests guards it by counting raw type occurrences. The elicitation request types were missed.

Fix

Mark the overridden mode() accessors on ElicitFormRequest and ElicitUrlRequest @JsonIgnore, mirroring Content.type(). The @JsonTypeInfo machinery still writes mode exactly once, and deserialization is unaffected since it uses the discriminator plus the @JsonCreator fromJson factories.

Tests

ElicitRequestJsonTests mirrors ContentJsonTests: it asserts each subtype serializes mode exactly once (counting raw occurrences, since the existing assertThatJson tree comparison silently collapses duplicate keys) and that both round-trip back to the correct subtype.

mvn -pl mcp-test -am test -Dtest=ElicitRequestJsonTests,ContentJsonTests,McpSchemaTests

All green (195 schema + 5 content + 4 new). Before the change the two count assertions fail (mode appears twice); after, they pass.

ElicitRequest declares its subtype discriminator with
@JsonTypeInfo(..., property = "mode"), so Jackson already writes the mode
property during serialization. ElicitFormRequest and ElicitUrlRequest also
annotated their mode() accessor with @JsonProperty("mode"), so mode was written
twice, producing a duplicate JSON key.

Mark the overridden mode() accessors @JsonIgnore, mirroring the existing fix on
Content.type(). Deserialization is unaffected (it uses the discriminator and the
@JsonCreator factories). Adds ElicitRequestJsonTests, mirroring ContentJsonTests.
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