astral-sh/ruff · warning

Workspace not found: {uri}

Error message

Workspace not found: {uri}

What it means

A workspace/didChangeWorkspaceFolders removal targeted a path that is not registered in the server's workspace map, so workspaces.unregister() returned false and the ensure! fired (session.rs:804). The server only knows folders it successfully registered during initialize or a prior add.

Source

Thrown at crates/ty_server/src/session.rs:804

    ///
    /// # Errors
    ///
    /// This returns an error if the workspace folder has already been removed
    /// or otherwise could not be found.
    pub(crate) fn remove_workspace_folder(
        &mut self,
        client: &Client,
        uri: &Uri,
    ) -> anyhow::Result<()> {
        tracing::info!("Removing workspace folder: {uri}");

        let path = uri
            .to_file_path()
            .map_err(|()| anyhow!("Workspace URI is not a file path: {uri}"))?;
        let workspace_path = SystemPathBuf::from_path_buf(path)
            .map_err(|path| anyhow!("Workspace path is not valid UTF-8: {}", path.display()))?;

        anyhow::ensure!(
            self.workspaces.unregister(&workspace_path),
            "Workspace not found: {uri}",
        );

        // Note that it is somewhat unclear whether we actually need to
        // clear diagnostics here. It seems that, at least in the case
        // of VS Code, it will auto-clear any diagnostics not found in
        // the workspace diagnostic response. Moreover, VS Code will
        // re-request workspace diagnostics after removing a workspace
        // folder.
        //
        // For now, we keep unconditionally clearing diagnostics on
        // opened text documents for reasons of good sense, but it's
        // possible that we don't even need to do that (when workspace
        // diagnostics are enabled).
        //
        // See: https://github.com/astral-sh/ruff/pull/22953#discussion_r2745255350

View on GitHub (pinned to 672bb4edf0)

Solutions

  1. Track added workspace folders client-side and only remove ones you added
  2. Ignore/log-and-continue on duplicate removal — state is already correct
  3. Verify the URI string matches exactly (encoding, trailing slash) the one used when adding
  4. Check the server log for a failed prior add of the same folder

Example fix

// before
removeWorkspaceFolder(uri);  // fired twice -> 'Workspace not found'

// after
const added = new Set();
function removeWorkspaceFolder(uri) {
  if (!added.has(uri)) return;  // idempotent
  added.delete(uri);
  client.notify('workspace/didChangeWorkspaceFolders', {
    event: { removed: [{ uri, name: uri }] },
  });
}
Defensive patterns

Strategy: validation

Validate before calling

// TS: idempotent removal backed by a client-side registry
const addedFolders = new Set<string>();
function removeFolder(uri: string) {
  const key = vscode.Uri.parse(uri).toString();
  if (!addedFolders.has(key)) return;
  addedFolders.delete(key);
  client.notify('workspace/didChangeWorkspaceFolders', {
    event: { removed: [{ uri: key, name: key }] },
  });
}

Type guard

const isRegisteredFolder = (uri: string): boolean => addedFolders.has(normalizeUri(uri));

Prevention

When it happens

Trigger: Removing a folder that was never added, removing the same folder twice, removing a folder whose earlier add failed (e.g. it hit the non-file-URI error), or a path/URI normalization mismatch (trailing slash, case, symlink).

Common situations: Editor restarts replaying folder state, duplicate remove events, races between add and remove during rapid project switching, or URI-vs-canonical-path discrepancies.

Related errors


AI-assisted analysis of astral-sh/ruff@672bb4edf0 (2026-08-16). Data as JSON: /api/errors/448eef05be31aa27. Report an issue: GitHub.