astral-sh/ruff · error

Document controller not available at

Error message

Document controller not available at `{uri}`

What it means

In `document_controller_for_key`, after the key maps to a URI, the server fetches a mutable controller from `self.documents`. If the URI is known but has no controller entry, the index is inconsistent and the server bails. This is the update-path counterpart of error 85.

Solutions

  1. Restart the Ruff server to rebuild the document index
  2. Reopen the affected document via didOpen, then resend changes
  3. If hacking on ruff_server, audit insert/remove paths so URI mappings and controllers are updated together
Defensive patterns

Strategy: try-catch

Try / catch

if let Err(e) = session.update_text_document(&key, changes, ver, enc) { if e.to_string().contains("Document controller not available") { reopen_document(key); retry_update(); } }

Prevention

When it happens

Trigger: Calling `update_text_document` or `update_notebook_document` with a key whose URI exists in the key-to-URI mapping but is absent from `self.documents`.

Common situations: Desynchronized index state after failed or partial document opens; close removed the controller but left the mapping; concurrent modification bugs in server internals.

Related errors


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

Appendix: source

Thrown at crates/ruff_server/src/session/index.rs:352

    }

    pub(super) fn client_settings(&self, key: &DocumentKey) -> Option<Arc<ClientSettings>> {
        let uri = self.uri_for_key(key)?;
        let WorkspaceSettings {
            client_settings, ..
        } = self.settings_for_uri(uri)?;
        Some(client_settings.clone())
    }

    fn document_controller_for_key(
        &mut self,
        key: &DocumentKey,
    ) -> crate::Result<&mut DocumentController> {
        let Some(uri) = self.uri_for_key(key).cloned() else {
            anyhow::bail!("Tried to open unavailable document `{key}`");
        };
        let Some(controller) = self.documents.get_mut(&uri) else {
            anyhow::bail!("Document controller not available at `{uri}`");
        };
        Ok(controller)
    }

    fn uri_for_key<'a>(&'a self, key: &'a DocumentKey) -> Option<&'a Uri> {
        match key {
            DocumentKey::Notebook(path) | DocumentKey::Text(path) => Some(path),
            DocumentKey::NotebookCell(uri) => self.notebook_cells.get(uri),
        }
    }

    fn settings_for_uri(&self, uri: &Uri) -> Option<&WorkspaceSettings> {
        if let Ok(path) = uri.to_file_path() {
            self.settings_for_path(&path)
        } else {
            // If there's only a single workspace, use that configuration for an untitled document.
            if self.settings.len() == 1 {
                tracing::debug!(

View on GitHub (pinned to 26f38c119c)