denoland/deno · error

Unable to convert definition info: {:#}

Error message

Unable to convert definition info: {:#}

What it means

Go-to-definition results from tsc (definition info entries) are converted into an LSP GotoDefinitionResponse via DocumentSpan::collect_into_goto_definition_response; this wraps a failure of that conversion. Failures usually come from mapping a definition's span in the TARGET document — resolving the target file's line index or converting its span can fail even though the file the request was made from is fine.

Source

Thrown at cli/lsp/ts_server.rs:565

      Self::Js(ts_server) => {
        let definition_info = ts_server
          .get_definition(
            snapshot.clone(),
            module,
            module.line_index.offset_tsc(position)?,
            token,
          )
          .await?;
        super::tsc::DocumentSpan::collect_into_goto_definition_response(
          definition_info
            .iter()
            .flat_map(|i| &i.definitions)
            .flatten()
            .map(|i| (&i.document_span, module)),
          snapshot,
          token,
        )
        .map_err(|err| anyhow!("Unable to convert definition info: {:#}", err))
      }
    }
  }

  pub async fn provide_type_definition(
    &self,
    module: &DocumentModule,
    position: lsp::Position,
    snapshot: &Arc<StateSnapshot>,
    token: &CancellationToken,
  ) -> Result<Option<lsp::request::GotoTypeDefinitionResponse>, AnyError> {
    match self {
      Self::Js(ts_server) => {
        let definition_info = ts_server
          .get_type_definition(
            snapshot.clone(),
            module,
            module.line_index.offset_tsc(position)?,

View on GitHub (pinned to 9ad36f7a2c)

Solutions

  1. Save dirty files (especially likely jump targets) and retry the navigation.
  2. Retry the request — transient snapshot races clear on the next attempt.
  3. Run "Deno: Restart Language Server" if a specific target file always fails.
  4. Update Deno; inspect the wrapped error after the colon in the language server output.
Defensive patterns

Strategy: retry

Try / catch

// Definition conversion failures are transient snapshot races on target
// documents; retry once, then surface a soft 'no definition found'.
async function definitionSafe(client, params) {
  try {
    return await client.sendRequest('textDocument/definition', params);
  } catch (err) {
    if (String(err?.message).includes('Unable to convert definition info')) {
      await sleep(250);
      return await client.sendRequest('textDocument/definition', params);
    }
    throw err;
  }
}

Prevention

When it happens

Trigger: A textDocument/definition request where one returned definition span fails to convert — the target document changed or was closed between snapshot and conversion, or the span falls outside the target's current content.

Common situations: Ctrl+click / Go to Definition immediately after edits in the destination file; definitions inside generated or just-created files whose snapshot state is inconsistent.

Related errors


AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20). Data as JSON: /api/errors/4bea4a06b4d1ed4c. Report an issue: GitHub.