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

  1. Verify the client sends a valid file:// URI in didOpen that matches the URIs used elsewhere (didChange/didClose).
  2. Update ruff-lsp / ruff server to the latest version; several snapshot/URI handling bugs were fixed.
  3. If the document is virtual (untitled, git:, etc.), disable Ruff for those schemes in the client settings.
  4. 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

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


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