astral-sh/ruff · error · anyhow::Error

JSON parsing failure: {json_err}

Error message

JSON parsing failure:
{json_err}

What it means

`cast_request` deserializes the JSON `params` of an incoming LSP request into the typed parameter struct for a specific request handler. When serde fails to parse the JSON into `Req::Params` (an `ExtractError::JsonError`), the server returns this error with code InvalidParams (-32602). It means the client sent params that do not match the LSP schema for that method.

Source

Thrown at crates/ty_server/src/server/api.rs:495

/// Tries to cast a serialized request from the server into
/// a parameter type for a specific request handler.
/// It is *highly* recommended to not override this function in your
/// implementation.
fn cast_request<Req>(
    request: server::Request,
) -> Result<(
    RequestId,
    <<Req as RequestHandler>::RequestType as Request>::Params,
)>
where
    Req: RequestHandler,
    <<Req as RequestHandler>::RequestType as Request>::Params: UnwindSafe,
{
    request
        .extract(Req::METHOD.as_str())
        .map_err(|err| match err {
            json_err @ server::ExtractError::JsonError { .. } => {
                anyhow::anyhow!("JSON parsing failure:\n{json_err}")
            }
            server::ExtractError::MethodMismatch(_) => {
                unreachable!(
                    "A method mismatch should not be possible here \
                    unless you've used a different handler (`Req`) \
                    than the one whose method name was matched against earlier."
                )
            }
        })
        .with_failure_code(server::ErrorCode::InvalidParams)
}

/// Sends back a response to the client, but only if the request wasn't cancelled.
fn respond<Req>(
    id: &RequestId,
    result: Result<<<Req as RequestHandler>::RequestType as Request>::Result>,
    client: &Client,
    log_guidance: &str,

View on GitHub (pinned to 26f38c119c)

Solutions

  1. Log the raw JSON `params` of the failing request and compare it with the LSP spec / ty's expected params type for that method
  2. Update the LSP client (or its ty extension) so it serializes params matching the current LSP schema
  3. If hand-crafting requests, wrap params in the exact object shape the method requires (e.g. `{"textDocument": {"uri": ...}, "position": {"line": ..., "character": ...}}`)
  4. Check for ty/client version mismatch and pin compatible versions

Example fix

// before (hand-crafted hover request)
{"jsonrpc":"2.0","id":1,"method":"textDocument/hover","params":{"uri":"file:///a.py","position":[3, 7]}}
// after
{"jsonrpc":"2.0","id":1,"method":"textDocument/hover","params":{"textDocument":{"uri":"file:///a.py"},"position":{"line":3,"character":7}}}
Defensive patterns

Strategy: validation

Validate before calling

// Validate a hover request payload before sending
function validHoverParams(p) {
  return p && typeof p === 'object'
    && p.textDocument && typeof p.textDocument.uri === 'string'
    && p.position && Number.isInteger(p.position.line)
    && Number.isInteger(p.position.character);
}
if (!validHoverParams(params)) throw new Error('invalid LSP hover params');
sendRequest('textDocument/hover', params);

Type guard

function isPosition(p) {
  return typeof p === 'object' && p !== null
    && Number.isInteger(p.line) && p.line >= 0
    && Number.isInteger(p.character) && p.character >= 0;
}
function isHoverParams(p) {
  return typeof p === 'object' && p !== null
    && typeof (p.textDocument && p.textDocument.uri) === 'string' && isPosition(p.position);
}

Prevention

When it happens

Trigger: The LSP client sends a request whose `params` field is missing, has the wrong shape (e.g. a string where an object is expected), or contains values of unexpected types, and the server extracts them via `request.extract::<Req>()`.

Common situations: A client or plugin speaking a slightly different LSP version than ty expects; a custom/bridging client (Emacs lsp-mode, Neovim, custom scripts) hand-crafting JSON-RPC requests; version skew after ty added a new field to a request's params.

Related errors


AI-assisted analysis of astral-sh/ruff@26f38c119c (2026-09-05). Data as JSON: /api/errors/5051b90e90f1da33. Report an issue: GitHub.