BoundaryML/baml · error

Document controller not available at

Error message

Document controller not available at `{}`

What it means

Raised by Index::document_controller_for_key when looking up a DocumentKey that is not in the documents map. Called by update_text_document, so most users see it as a failure to apply didChange/didOpen updates for a URI the server never registered.

Solutions

  1. Send textDocument/didOpen before any didChange for the URI
  2. Compare the exact URI string the server registered with the one being sent (scheme, casing, encoding)
  3. If the server was restarted, re-open the document to repopulate the index
  4. Add client-side tracking so changes are only sent for known-open documents

Example fix

// before
sendDidChange(uri, changes);
// after
if (!serverKnows(uri)) await sendDidOpen(uri, text);
sendDidChange(uri, changes);
Defensive patterns

Strategy: validation

Validate before calling

if (!serverKnownDocuments.has(normalizeUri(uri))) await sendDidOpen(uri, text);

Type guard

const knows = (uri: string): boolean => serverKnownDocuments.has(uri);

Try / catch

try { await sendDidChange(uri, changes); } catch (e) { if (String(e).includes('not available')) { await sendDidOpen(uri, currentText); await sendDidChange(uri, changes); } else throw e; }

Prevention

When it happens

Trigger: update_text_document (or other controller consumers) invoked with a key absent from the index: missing didOpen, URI case/scheme mismatch, or index cleared by reload.

Common situations: Client sends didChange before didOpen; server restarted and lost state while client kept editing; URI normalization differences (e.g. file:// vs untitled:, path casing on Windows).

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12). Data as JSON: /api/errors/fcc326d969e500c4. Report an issue: GitHub.

Appendix: source

Thrown at engine/language_server/src/session/index.rs:96

        // let Some(url) = self.url_for_key(key).cloned() else {
        //     anyhow::bail!("Tried to close unavailable document `{key}`");
        // };

        let Some(_) = self.documents.remove(document_key) else {
            anyhow::bail!(
                "tried to close document that didn't exist at {}",
                document_key
            )
        };
        Ok(())
    }

    pub fn document_controller_for_key(
        &mut self,
        document_key: &DocumentKey,
    ) -> anyhow::Result<&mut DocumentController> {
        let Some(controller) = self.documents.get_mut(document_key) else {
            anyhow::bail!("Document controller not available at `{}`", document_key);
        };
        Ok(controller)
    }

    // fn url_for_key<'a>(&'a self, key: &'a DocumentKey) -> Option<&'a Url> {
    //     match key {
    //         DocumentKey::Text(path) => Some(path),
    //     }
    // }
}

/// A mutable handler to an underlying document.
/// TODO: Don't use an enum here.
#[derive(Debug)]
pub enum DocumentController {
    Text(Arc<TextDocument>),
}

View on GitHub (pinned to bd85ce9dee)