{"record":{"id":"51f04becffc3d59e","repo":"facebook/flow","slug":"convert-to-server-uris-invalid-file-url","errorCode":null,"errorMessage":"convert_to_server_uris: invalid file url","messagePattern":"convert_to_server_uris: invalid file url","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"rust_port/crates/flow_lsp_server/src/flow_lsp.rs","lineNumber":1214,"sourceCode":"                    #[allow(clippy::arc_with_non_send_sync)]\n                    let mapper = std::sync::Arc::new(mapper);\n                    let server_mapper = lsp_prot::default_message_from_server_mapper(mapper);\n                    Event::ServerMessage((server_mapper.of_message_from_server)(\n                        &server_mapper,\n                        msg,\n                    ))\n                }\n                Event::ClientMessage(msg, metadata) => Event::ClientMessage(msg, metadata),\n                Event::Tick => Event::Tick,\n            }\n        }\n    }\n}\n\nfn convert_to_server_uris(request: lsp_prot::Request) -> lsp_prot::Request {\n    let server_uri_of_client_uri = |uri: DocumentUri| -> DocumentUri {\n        let path =\n            lsp_helpers::lsp_uri_to_path(&uri).expect(\"convert_to_server_uris: invalid file url\");\n        let path = FilePath::from(path);\n        let canonical = flow_common::files::cached_canonicalize(&path).unwrap_or(path);\n        let canonical = canonical.to_string_lossy();\n        lsp_helpers::path_to_lsp_uri(canonical.as_ref(), \"\")\n    };\n    let mut client_to_server_mapper = lsp_mapper::default_mapper();\n    client_to_server_mapper.of_document_uri =\n        Box::new(move |_mapper, uri| server_uri_of_client_uri(uri));\n    match request {\n        lsp_prot::Request::Subscribe => lsp_prot::Request::Subscribe,\n        lsp_prot::Request::LspToServer(msg) => {\n            let mapped = (client_to_server_mapper.of_lsp_message)(&client_to_server_mapper, msg);\n            lsp_prot::Request::LspToServer(mapped)\n        }\n        lsp_prot::Request::LiveErrorsRequest(uri) => {\n            let mapped_uri =\n                (client_to_server_mapper.of_document_uri)(&client_to_server_mapper, uri);\n            lsp_prot::Request::LiveErrorsRequest(mapped_uri)","sourceCodeStart":1196,"sourceCodeEnd":1232,"githubUrl":"https://github.com/facebook/flow/blob/5c865861998a8ccb7dbc82b0c1f511e9ef60c3d9/rust_port/crates/flow_lsp_server/src/flow_lsp.rs#L1196-L1232","documentation":"Panics when lsp_uri_to_path returns Err while rewriting client URIs to server (canonicalized) URIs for an incoming LSP request. The helper accepts scheme-less strings as paths, handles file: via file_url::parse, and errors for any other scheme (untitled:, http:, vscode-remote:, git:) or a file: URL that fails to parse (bad percent-encoding, malformed host form).","triggerScenarios":"An editor sends a request whose TextDocumentIdentifier references an unsaved buffer (untitled: scheme), a virtual/webview document, or a remote scheme; a client sends a file: URI with invalid encoding; plugins issuing requests over custom schemes.","commonSituations":"Users running commands on untitled scratch buffers; VS Code remote/webview URIs (vscode-remote:, vscode-userdata:); Jupyter/virtual documents in editors driving the Flow language server.","solutions":["Check the URI scheme before conversion and skip/answer empty for non-file: URIs","Fix the client/editor plugin so it only sends file: document URIs to the server","Wrap canonicalization failures with cached_canonicalize's fallback (unwrap_or(path)) instead of panicking on unparseable file URLs"],"exampleFix":"// before\nlet path = lsp_helpers::lsp_uri_to_path(&uri)\n    .expect(\"convert_to_server_uris: invalid file url\");\n\n// after — pass non-file URIs through untouched\nlet path = match lsp_helpers::lsp_uri_to_path(&uri) {\n    Ok(path) => FilePath::from(path),\n    Err(_) => return uri, // untitled:/virtual docs: leave the URI as-is\n};","handlingStrategy":"validation","validationCode":"// Only canonicalize real file documents; pass others through\nlet uri_str = uri.as_str();\nif !uri_str.starts_with(\"file:\") {\n    return uri; // untitled:/virtual documents: leave untouched\n}\nlet path = lsp_helpers::lsp_uri_to_path(&uri)?; // now safe to require","typeGuard":"fn is_file_uri(uri: &lsp_types::Url) -> bool {\n    uri.scheme().eq_ignore_ascii_case(\"file\")\n}","tryCatchPattern":null,"preventionTips":["Guard on the URI scheme before any lsp_uri_to_path call","Don't issue server-side requests against unsaved (untitled:) buffers in editor plugins","Add regression tests that feed untitled:/http: URIs into request handling"],"tags":["rust","lsp","uri","language-server","validation"],"backgroundTag":"uri-scheme-not-supported","analyzedSha":"5c865861998a8ccb7dbc82b0c1f511e9ef60c3d9","analyzedAt":"2026-08-20T10:41:37.992Z","contentChangedAt":"2026-08-20T10:41:37.992Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}