astral-sh/ruff · error

Workspace URI is not a file or directory: {uri:?}

Error message

Workspace URI is not a file or directory: {uri:?}

What it means

When registering a workspace folder (from initialize's workspaceFolders or a later add), uri.to_file_path() failed, so the URI is not convertible to a filesystem path (session.rs:1539). Registration of that folder aborts; only file-scheme URIs are supported.

Source

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

}

impl Workspaces {
    /// Registers a new workspace with the given URI and default settings for the workspace.
    ///
    /// This returns `true` when this workspace is added and `false`
    /// when it has already been added.
    ///
    /// It's the caller's responsibility to later call
    /// [`Session::request_uninitialized_workspace_folder_configurations`] with
    /// the resolved settings for this workspace. Registering and initializing
    /// a workspace is a two-step process because the workspace are announced
    /// to the server during the `initialize` request, but the resolved
    /// settings are only available after the client has responded to the
    /// `workspace/configuration` request.
    fn register(&mut self, uri: Uri) -> anyhow::Result<bool> {
        let path = uri
            .to_file_path()
            .map_err(|()| anyhow!("Workspace URI is not a file or directory: {uri:?}"))?;

        // Realistically I don't think this can fail because we got the path from a Uri
        let system_path = SystemPathBuf::from_path_buf(path)
            .map_err(|_| anyhow!("Workspace URI is not valid UTF8"))?;

        if self.workspaces.contains_key(&system_path) {
            return Ok(false);
        }

        self.workspaces.insert(
            system_path,
            Workspace {
                uri,
                settings: Arc::new(WorkspaceSettings::default()),
                initialized: false,
            },
        );
        Ok(true)

View on GitHub (pinned to 672bb4edf0)

Solutions

  1. Filter initialize's workspaceFolders to `file://` URIs only
  2. Fix the client to send real filesystem folders
  3. For genuinely virtual workspaces, accept that ty cannot attach to them

Example fix

// before
workspaceFolders: [{ uri: 'untitled:Workspace-1', name: 'ws' }]

// after
workspaceFolders: [{ uri: 'file:///home/me/project', name: 'project' }]
Defensive patterns

Strategy: type-guard

Validate before calling

// TS: only announce convertible folders at initialize
const folders = vscode.workspace.workspaceFolders
  ?.filter(f => f.uri.scheme === 'file')
  .map(f => ({ uri: f.uri.toString(), name: f.name })) ?? [];

Type guard

const isFileWorkspaceFolder = (f: { uri: string | vscode.Uri }): boolean =>
  (typeof f.uri === 'string' ? vscode.Uri.parse(f.uri) : f.uri).scheme === 'file';

Prevention

When it happens

Trigger: Announcing a workspace folder with a non-`file:` URI — untitled:, vscode-remote with a non-file inner scheme, or virtual/remote document schemes lsp-types cannot convert.

Common situations: Browser-based or remote editors forwarding virtual workspaces, extensions adding synthesized folders, or clients passing rootUri in a non-file scheme.

Related errors


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