`progressToken` is a reserved `_meta` member the spec constrains to
`string | integer` (`ProgressTokenSchema = z.union([z.string(),
z.number().int()])`). Every other value may be any JSON after #1910, which is
what makes this one key need its own check: before the widening a value was
always a string and therefore always valid, but now a float, an object or an
array can land there, and a conforming server would reject the whole request.
`progressTokenOf` only governed whether a progress callback was wired up, so a
bad value still rode out inside `_meta`. Sanitize in `mergeMeta` instead — the
single point every `_meta` flows through — dropping just the offending member
with a warning. The key is optional, so the request stays well-formed and
simply asks for no progress.
Note the exposure only exists with `progress: false`. With progress on (the
default) the SDK sets `onprogress` and stamps its own message id over
`_meta.progressToken`, so a caller's value never reaches the wire either way.
The new tests therefore run with progress disabled, which is the configuration
that can actually ship a bad token: five invalid shapes dropped (float, object,
array, null, boolean) with the sibling keys left intact, and string/integer
preserved.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0177mPHAdECD18nLLCTwR5rh
Signed-off-by: cliffhall <cliff@futurescale.com>