Skip to content

input-required-result: harness sends the literal string "undefined" as an inputResponses key when round 1 names no input requests #440

Description

@marcus-kepler-92

Following up on #439 item 3 — I went to look at that one guard and found a
round-2 consequence that issue doesn't cover.

InputRequiredResult.inputRequests is optional (required: ["resultType"] in the
draft schema), and sep-2322.yaml states the rule as "at least one of
inputRequests or requestState". So a server answering

{ "resultType": "input_required", "requestState": "s-1", "inputRequests": {} }

is conformant, and the round-1 checks are right to pass it. But five round-2 sites
then take the first key of that map without checking it exists:

const inputKey = Object.keys(r1Result.inputRequests!)[0];   // undefined
// ...
inputResponses: { [inputKey]: mockElicitResponse({ ok: true }) }

A computed key stringifies, so the harness puts the literal string "undefined" on
the wire.

Repro

Against a probe server returning the result above for every MRTR tool and
prompts/get, with requestState rotating so round 2 is reachable:

node dist/index.js server --url http://localhost:PORT/mcp \
  --scenario input-required-result-request-state --spec-version 2026-07-28

The probe logged the inputResponses keys it received across four scenarios:

tools/call  test_input_required_result_request_state   -> ["undefined"]
tools/call  test_input_required_result_multi_round     -> ["undefined"]
tools/call  test_input_required_result_multi_round     -> ["undefined"]
prompts/get test_input_required_result_prompt          -> ["undefined"]
tools/call  test_input_required_result_tampered_state  -> ["undefined"]

Sites: :539, :865, :908, :1095, :1337. The two equivalents at
:269 and :405 are unreachable here — their round-1 arms use
Object.keys(...)[0] behind a !key guard that already failed the scenario.

Why it matters

The round-2 check then fails, and the report attributes that to the server:

[sep-2322-request-state-incomplete] SUCCESS Server returns InputRequiredResult with both inputRequests and requestState
[sep-2322-request-state-complete  ] FAILURE Server validates echoed requestState and returns complete result
[wire-schema-valid                ] SUCCESS Every JSON-RPC message the implementation sent is valid ...

wire-schema-valid passes because inputResponses keys are unconstrained, so
nothing else catches it either.

Suggested direction

Gate round 2 on actually having a key, and report the prerequisite rather than
sending a request that can't be answered — the convention #372 established for
missing prerequisites. Each of the five sites is two lines; happy to send a PR.

negative-mrtr.test.ts plus sep-2322-mrtr-broken-server already give a place to
assert it, so this can carry a regression test without new harness plumbing.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions