astral-sh/ruff · error
InternalError
InternalError
Error message
Unable to take snapshot for document with URI {uri} What it means
The Ruff LSP server failed to produce a diagnostic snapshot for a document after a `textDocument/didOpen` notification. `take_snapshot` returns None when the URI is not tracked by the session (e.g. the document was never registered or was removed). The server surfaces this as an InternalError response instead of silently skipping diagnostics.
Source
Thrown at crates/ruff_server/src/server/api/notifications/did_open.rs:37
text_document:
types::TextDocumentItem {
uri,
text,
version,
language_id,
},
}: types::DidOpenTextDocumentParams,
) -> Result<()> {
let document = TextDocument::new(text, version).with_language_id(language_id);
session.open_text_document(uri.clone(), document);
// Publish diagnostics if the client doesn't support pull diagnostics
if !session.resolved_client_capabilities().pull_diagnostics {
let snapshot = session
.take_snapshot(uri.clone())
.ok_or_else(|| {
anyhow::anyhow!("Unable to take snapshot for document with URI {uri}")
})
.with_failure_code(lsp_server::ErrorCode::InternalError)?;
publish_diagnostics_for_document(&snapshot, client)?;
}
Ok(())
}
}
View on GitHub (pinned to 26f38c119c)
Solutions
- Verify the client sends a valid file:// URI in didOpen that matches the URIs used elsewhere (didChange/didClose).
- Update ruff-lsp / ruff server to the latest version; several snapshot/URI handling bugs were fixed.
- If the document is virtual (untitled, git:, etc.), disable Ruff for those schemes in the client settings.
- Restart the language server after workspace folder changes so the document index is rebuilt.
Example fix
// before: sending a non-standard URI from a custom client
{ "method": "textDocument/didOpen", "params": { "textDocument": { "uri": "mem://buffer.py", ... } } }
// after: use a file URI the server can index
{ "method": "textDocument/didOpen", "params": { "textDocument": { "uri": "file:///home/user/buffer.py", ... } } } Defensive patterns
Strategy: try-catch
Try / catch
// client-side: wrap server dispatch
try {
await connection.sendNotification('textDocument/didOpen', params);
} catch (e) {
if (String(e.message).includes('Unable to take snapshot')) {
console.warn(`Ruff could not index ${params.textDocument.uri}; skipping diagnostics`);
}
} Prevention
- Only send didOpen for file:// URIs the server can track.
- Keep didOpen/didClose pairing correct to avoid racing the document index.
- Restart the server after workspace folder changes.
- Keep the ruff server version current.
When it happens
Trigger: A did_open notification arrives whose URI is not present in the session's document index — e.g. the client opens a document Ruff never saw via workspace/didChangeWatchedFiles initialization, a URI scheme Ruff does not track, or a race where the document was closed before diagnostics were taken.
Common situations: VS Code (or another LSP client) with virtual/non-file documents, symlinked or URI-encoded paths that mismatch the index key, multiple workspace folders where the file belongs to an ignored workspace, or client bugs double-sending didOpen after a server restart.
Related errors
- failed to deserialize diagnostic data: {err}
- Expected a ty `File`, found a ruff `SourceFile`
- InternalError
- should be set because `extract_if` only yields elements with
- Expected Stmt::ImportFrom
AI-assisted analysis of astral-sh/ruff@26f38c119c (2026-09-05).
Data as JSON: /api/errors/ff5b484654c5d019.
Report an issue: GitHub.