{"record":{"id":"9101182f67982fdd","repo":"rust-lang/rust-analyzer","slug":"unable-to-get-abspath","errorCode":null,"errorMessage":"Unable to get AbsPath","messagePattern":"Unable to get AbsPath","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/rust-analyzer/src/main_loop.rs","lineNumber":1099,"sourceCode":"    }\n\n    fn handle_deferred_task(&mut self, task: DeferredTask) {\n        match task {\n            DeferredTask::CheckIfIndexed(uri) => {\n                let snap = self.snapshot();\n\n                self.task_pool.handle.spawn_with_sender(ThreadIntent::Worker, move |sender| {\n                    let _p = tracing::info_span!(\"GlobalState::check_if_indexed\").entered();\n                    tracing::debug!(?uri, \"handling uri\");\n                    let Some(id) = from_proto::file_id(&snap, &uri).expect(\"unable to get FileId\")\n                    else {\n                        return;\n                    };\n                    if let Ok(crates) = &snap.analysis.crates_for(id) {\n                        if crates.is_empty() {\n                            if snap.config.discover_workspace_config().is_some() {\n                                let path =\n                                    from_proto::abs_path(&uri).expect(\"Unable to get AbsPath\");\n                                let arg = DiscoverProjectParam::Path(path);\n                                sender.send(Task::DiscoverLinkedProjects(arg)).unwrap();\n                            }\n                        } else {\n                            tracing::debug!(?uri, \"is indexed\");\n                        }\n                    }\n                });\n            }\n            DeferredTask::CheckProcMacroSources(modified_rust_files) => {\n                let analysis = AssertUnwindSafe(self.snapshot().analysis);\n                self.task_pool.handle.spawn_with_sender(stdx::thread::ThreadIntent::Worker, {\n                    move |sender| {\n                        if modified_rust_files.into_iter().any(|file_id| {\n                            // FIXME: Check whether these files could be build script related\n                            match analysis.crates_for(file_id) {\n                                Ok(crates) => crates.iter().any(|&krate| {\n                                    analysis.is_proc_macro_crate(krate).is_ok_and(|it| it)","sourceCodeStart":1081,"sourceCodeEnd":1117,"githubUrl":"https://github.com/rust-lang/rust-analyzer/blob/e8f7e90aa3e7b26aa9a000200f606c1078da99ec/crates/rust-analyzer/src/main_loop.rs#L1081-L1117","documentation":"In the same CheckIfIndexed task, when a file has no crates and workspace discovery is configured, the URI is converted to an AbsPath to request linked-project discovery. from_proto::abs_path only succeeds for file:// URIs; the expect panics for any other scheme. The surrounding logic assumes discovery only runs on real filesystem paths, so a non-file URI here is an unhandled input.","triggerScenarios":"Workspace discovery (rust.analyzer.linkedProjects / discoverWorkspaceConfig) active while a didOpen arrives for a non-file URI — untitled editors, virtual documents, remote scheme URIs — whose file has zero crates, triggering the DiscoverLinkedProjects path.","commonSituations":"Users with linkedProjects/discovery config enabled opening scratch or notebook Rust files, remote development setups where URIs include authority components, misconfigured discovery pointing at virtual workspaces.","solutions":["Restrict discovery config to real filesystem directories and do not open virtual/untitled .rs editors when it is enabled.","Upgrade rust-analyzer: guard this conversion with a graceful return instead of expect.","Check rust.analyzer.workspace.discoverConfig in settings and remove entries matching virtual/remote roots.","Reproduce with the logged `?uri` to find which client feature sends the non-file URI and disable it."],"exampleFix":"// before\nlet path = from_proto::abs_path(&uri).expect(\"Unable to get AbsPath\");\n// after: only attempt discovery for real paths\nlet Some(path) = from_proto::abs_path(&uri) else { return; };","handlingStrategy":"validation","validationCode":"// server-side guard: only run discovery for file:// URIs\nif uri.scheme() != \"file\" { return; }\nlet path = from_proto::abs_path(&uri).expect(\"Unable to get AbsPath\");","typeGuard":"fn to_abs_path(uri: &lsp_types::Url) -> Option<AbsPathBuf> {\n    from_proto::abs_path(uri).ok()\n}","tryCatchPattern":null,"preventionTips":["Configure workspace discovery only for real filesystem directories.","Avoid opening untitled/notebook Rust editors while discovery config is active.","Audit linkedProjects/discoverConfig entries for remote or virtual roots.","Update rust-analyzer so the conversion failure returns instead of panicking."],"tags":["lsp","uri","panic","workspace-discovery","virtual-documents"],"backgroundTag":"non-file-uri-path-conversion","analyzedSha":"e8f7e90aa3e7b26aa9a000200f606c1078da99ec","analyzedAt":"2026-09-03T21:08:06.959Z","contentChangedAt":"2026-09-03T21:08:06.959Z","schemaVersion":2},"datasetVersion":"2026-09-11T07:07:21.782Z"}