rust-lang/rust-analyzer · warning · anyhow::Error
Invalid LSP resolve data
Error message
Invalid LSP resolve data
What it means
`handle_inlay_hints_resolve` stores an opaque resolve blob (range, hash, etc.) inside inlay hint `data`. Before re-resolving, it validates that the referenced file still exists in the snapshot via `snap.file_exists(file_id)`; if not, the stored data is considered corrupt or stale in a way that cannot be gracefully recovered, so it fails with `Invalid LSP resolve data` via `anyhow::ensure!`.
Source
Thrown at crates/rust-analyzer/src/handlers/request.rs:1859
pub(crate) fn handle_inlay_hints_resolve(
snap: GlobalStateSnapshot,
mut original_hint: InlayHint,
) -> anyhow::Result<InlayHint> {
let _p = tracing::info_span!("handle_inlay_hints_resolve").entered();
let Some(data) = original_hint.data.take() else {
return Ok(original_hint);
};
let resolve_data: lsp_ext::InlayHintResolveData = serde_json::from_value(data)?;
let file_id = FileId::from_raw(resolve_data.file_id);
if resolve_data.version != snap.file_version(file_id) {
tracing::warn!("Inlay hint resolve data is outdated");
return Ok(original_hint);
}
let Some(hash) = resolve_data.hash.parse().ok() else {
return Ok(original_hint);
};
anyhow::ensure!(snap.file_exists(file_id), "Invalid LSP resolve data");
let line_index = snap.file_line_index(file_id)?;
let range = from_proto::text_range(&line_index, resolve_data.resolve_range)?;
let mut forced_resolve_inlay_hints_config = snap.config.inlay_hints(snap.minicore());
forced_resolve_inlay_hints_config.fields_to_resolve = InlayFieldsToResolve::empty();
let resolve_hints = snap.analysis.inlay_hints_resolve(
&forced_resolve_inlay_hints_config,
file_id,
range,
hash,
|hint| {
std::hash::BuildHasher::hash_one(
&std::hash::BuildHasherDefault::<ide_db::FxHasher>::default(),
hint,
)
},
)?;View on GitHub (pinned to e8f7e90aa3)
Solutions
- Have the client discard the stale hint and re-request `textDocument/inlayHint` for the current document.
- Reopen/reload the file in the editor so fresh hints (without stale data) are produced.
- If implementing a client, never cache inlay hint `data` beyond the server session.
- As a workaround, restart the language server to reset vfs state.
Example fix
// client-side before resolveHint(oldCachedHint); // after const hints = await requestInlayHints(uri); await resolveHint(hints.find(h => h.position === pos));
Defensive patterns
Strategy: try-catch
Validate before calling
// client-side: only resolve hints obtained in the same session for a still-open document
function canResolve(hint: InlayHint, openUris: Set<string>): boolean {
const fid = (hint.data as any)?.file_id;
return hint.data != null && fid != null && openUris.has(currentUri);
} Type guard
function hasValidResolveData(hint: InlayHint): boolean {
const d = hint.data as any;
return !!d && typeof d === "object" && "resolve_range" in d && "hash" in d && "file_id" in d;
} Try / catch
try {
return await client.sendRequest("inlayHint/resolve", hint);
} catch (e) {
// stale/invalid resolve data: drop the blob and refetch hints for the document
log.warn("inlayHint/resolve failed, refetching", e);
return (await client.sendRequest("textDocument/inlayHint", { textDocument: { uri }, range: fullRange }))[0] ?? hint;
} Prevention
- Never reuse inlay hint `data` blobs across LSP sessions or file deletions.
- Re-request inlay hints whenever the document is saved/reloaded externally.
- Treat resolve failures as non-fatal and fall back to the un-resolved hint.
When it happens
Trigger: A client sends `inlayHint/resolve` with hint `data` whose `file_id`/`hash` blob points to a file that no longer exists in the server's vfs snapshot (file deleted, workspace changed, or a fabricated/tampered `data` payload).
Common situations: Stale editor state resolving hints after a file was closed/deleted; protocol fuzzing or third-party clients reusing cached hint data across sessions; version drift between a saved hint and the current workspace.
Related errors
- No file available to rename
- inconsistent text range
- No references found at position
- client exited without proper shutdown sequence
- {loop_e} {join_e}
AI-assisted analysis of rust-lang/rust-analyzer@e8f7e90aa3 (2026-09-03).
Data as JSON: /api/errors/2317c474bdf01965.
Report an issue: GitHub.