{"record":{"id":"fa12d5e2839c55df","repo":"astral-sh/ruff","slug":"failed-to-convert-workspace-uri-to-file-path-wor","errorCode":null,"errorMessage":"Failed to convert workspace URI to file path: {workspace_uri}","messagePattern":"Failed to convert workspace URI to file path: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/ruff_server/src/session/index.rs","lineNumber":188,"sourceCode":"\n        notebook.update(cells, metadata, new_version, encoding)?;\n        Ok(())\n    }\n\n    pub(super) fn open_workspace_folder(\n        &mut self,\n        uri: Uri,\n        global: &GlobalClientSettings,\n        client: &Client,\n    ) -> crate::Result<()> {\n        // TODO(jane): Find a way for workspace client settings to be added or changed dynamically.\n        self.settings\n            .register_workspace(&Workspace::new(uri), global, client)\n    }\n\n    pub(super) fn close_workspace_folder(&mut self, workspace_uri: &Uri) -> crate::Result<()> {\n        let workspace_path = workspace_uri.to_file_path().map_err(|()| {\n            anyhow!(\"Failed to convert workspace URI to file path: {workspace_uri}\")\n        })?;\n\n        self.settings\n            .remove(&workspace_path)\n            .ok_or_else(|| anyhow!(\"Tried to remove non-existent workspace URI {workspace_uri}\"))?;\n\n        // O(n) complexity, which isn't ideal... but this is an uncommon operation.\n        self.documents\n            .retain(|uri, _| !Path::new(uri.path()).starts_with(&workspace_path));\n        self.notebook_cells\n            .retain(|_, uri| !Path::new(uri.path()).starts_with(&workspace_path));\n\n        Ok(())\n    }\n\n    pub(super) fn make_document_ref(\n        &self,\n        key: DocumentKey,","sourceCodeStart":170,"sourceCodeEnd":206,"githubUrl":"https://github.com/astral-sh/ruff/blob/26f38c119cac42e4d320ba08f09224fdec74af2c/crates/ruff_server/src/session/index.rs#L170-L206","documentation":"When closing a workspace folder, Ruff must convert its URI to a file path to look up matching settings. URIs that are not `file://` (or that cannot be mapped to a path on the current platform) fail `to_file_path()` and produce this error, aborting the folder close.","triggerScenarios":"A `workspace/didChangeWorkspaceFolders` remove event carries a non-file URI (untitled:, vfs:, remote authority URIs) or a file URI with a scheme/percent-encoding that cannot map to a filesystem path.","commonSituations":"Remote development (SSH/containers/devcontainers) where workspace URIs are virtual, untitled multi-root workspaces, or clients on Windows sending URIs Ruff's URI parser cannot convert.","solutions":["Only register/remove file:// workspace folders; virtual workspaces are unsupported by this code path.","Update Ruff — newer versions warn and ignore non-file workspaces instead of erroring.","If using remote development, open the folder through the remote extension so a mapped file URI is provided."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"function isFileUri(uri) { return typeof uri === 'string' && uri.startsWith('file:'); }\nif (removedFolders.some(f => !isFileUri(f.uri))) {\n  console.warn('skipping non-file workspace folder removal:', f.uri);\n}","typeGuard":"function isConvertibleUri(u) { return typeof u === 'string' && u.startsWith('file://'); }","tryCatchPattern":"try {\n  await connection.notify('workspace/didChangeWorkspaceFolders', { event: { removed } });\n} catch (e) {\n  if (String(e.message).includes('Failed to convert workspace URI')) {\n    console.warn('non-file workspace ignored by Ruff');\n  } else { throw e; }\n}","preventionTips":["Register only on-disk folders with the Ruff server.","Exclude virtual/remote schemes (untitled:, vscode-remote:) from folder events sent to Ruff.","Check server logs for 'Ruff does not support non-file workspaces'.","Keep the server updated for more tolerant URI handling."],"tags":["lsp","ruff","workspace","uri"],"backgroundTag":"uri-to-file-path-conversion-failed","analyzedSha":"26f38c119cac42e4d320ba08f09224fdec74af2c","analyzedAt":"2026-09-05T10:32:37.492Z","contentChangedAt":"2026-09-05T10:32:37.492Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}