denoland/deno · error
Unable to convert document highlights: {:#}
Error message
Unable to convert document highlights: {:#} What it means
After tsc returns document highlights (occurrences of the symbol under the cursor), each is converted to an LSP highlight range with to_highlight; this wraps a conversion failure. The common root cause is a highlight span that fails to map through the module's line index, typically because the document changed between the tsc query and the conversion, or conversion was cancelled mid-way.
Source
Thrown at cli/lsp/ts_server.rs:528
token: &CancellationToken,
) -> Result<Option<Vec<lsp::DocumentHighlight>>, AnyError> {
match self {
Self::Js(ts_server) => {
let highlights = ts_server
.get_document_highlights(
snapshot,
module,
module.line_index.offset_tsc(position)?,
token,
)
.await?;
highlights
.map(|highlights| {
highlights
.into_iter()
.map(|dh| {
dh.to_highlight(&module.line_index, token).map_err(|err| {
anyhow!("Unable to convert document highlights: {:#}", err)
})
})
.collect::<Result<Vec<_>, _>>()
.map(|s| s.into_iter().flatten().collect())
})
.transpose()
}
}
}
pub async fn provide_definition(
&self,
module: &DocumentModule,
position: lsp::Position,
snapshot: &Arc<StateSnapshot>,
token: &CancellationToken,
) -> Result<Option<lsp::GotoDefinitionResponse>, AnyError> {
match self {View on GitHub (pinned to 9ad36f7a2c)
Solutions
- Let edits settle and trigger the highlight again (move the cursor) — nearly always transient.
- Save the file to force a full sync, then retry.
- Run "Deno: Restart Language Server" if highlights stay broken for a file.
- Update Deno; check the wrapped error text in the language server output if it persists.
Defensive patterns
Strategy: retry
Try / catch
// Highlight failures stem from stale line-index mappings; the next
// request after edits settle succeeds.
async function highlightsWithRetry(client, params) {
try {
return await client.sendRequest('textDocument/documentHighlight', params);
} catch (err) {
if (String(err?.message).includes('document highlights')) {
await sleep(250);
return await client.sendRequest('textDocument/documentHighlight', params);
}
throw err;
}
} Prevention
- Trigger occurrence highlights on a settled cursor position rather than mid-edit
- Save to force a snapshot sync when highlights stop appearing
- Restart the language server and update Deno if it persists
When it happens
Trigger: A textDocument/documentHighlight request where a returned span is out of bounds for the current line index — rapid edits between request and conversion, a stale snapshot, or cancellation during the mapping loop.
Common situations: Selecting/typing over occurrences while highlight requests are in flight; failures appearing intermittently during fast editing and disappearing on the next request.
Related errors
- Error getting navigation tree for "{}": {:#}
- Unable to convert fix: {:#}
- Unable to get refactor info from TypeScript: {:#}
- Unable to convert refactor info: {:#}
- Unable to get organize imports edit from TypeScript: {:#}
AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20).
Data as JSON: /api/errors/cbbfc89a40e96602.
Report an issue: GitHub.