{"record":{"id":"b5bfae7e6931325b","repo":"Automattic/harper","slug":"unable-to-convert-uri-to-file-path","errorCode":null,"errorMessage":"Unable to convert URI to file path.","messagePattern":"Unable to convert URI to file path\\.","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"harper-ls/src/backend.rs","lineNumber":272,"sourceCode":"            exclude_patterns,\n        ) = {\n            let config = self.config.read().await;\n            (\n                config.lint_config.clone(),\n                config.markdown_options,\n                config.isolate_english,\n                config.dialect,\n                config.max_file_length,\n                config.exclude_patterns.clone(),\n            )\n        };\n\n        let mut doc_lock = self.doc_state.lock().await;\n\n        if !exclude_patterns.is_empty()\n            && exclude_patterns.is_match(\n                uri.to_file_path()\n                    .ok_or_else(|| anyhow!(\"Unable to convert URI to file path.\"))?,\n            )\n        {\n            doc_lock.remove(uri);\n            return Ok(());\n        }\n\n        let ignored_lints = self.load_ignored_lints(uri).await.unwrap_or_default();\n\n        let dict = Arc::new(\n            self.generate_file_dictionary(uri)\n                .await\n                .context(\"Unable to generate the file dictionary.\")?,\n        );\n\n        let doc_state = doc_lock.entry(uri.clone()).or_insert_with(|| {\n            info!(\"Constructing new LintGroup for new document.\");\n\n            DocumentState {","sourceCodeStart":254,"sourceCodeEnd":290,"githubUrl":"https://github.com/Automattic/harper/blob/5fe7d5ab76492d83f3ecdbc3f1da83c75dcb6f83/harper-ls/src/backend.rs#L254-L290","documentation":"`update_document` matches the incoming document URI against the configured exclude patterns using GlobSet. To do that it needs a filesystem path, so it calls `uri.to_file_path()`; for non-file or malformed URIs this is None and the update aborts with \"Unable to convert URI to file path.\"","triggerScenarios":"did_open or did_change events for documents whose URI is not a file URL (untitled:, remote:, custom schemes) or a malformed file:// URI, while any excludePatterns are configured.","commonSituations":"Unsaved scratch buffers in VS Code/Neovim, remote or container development schemes, or clients that send opaque URIs; especially visible once users configure excludePatterns, since the conversion only happens when exclusions exist.","solutions":["Save the document to disk so its URI is a valid file:// URL.","Clear excludePatterns to bypass path conversion (the exclusion check is skipped when no patterns are set).","For remote/virtual schemes, run the language server on the host where files actually live.","Fix the client's URI construction (authority/percent-encoding) if the file URI is malformed."],"exampleFix":"// before\nexcludePatterns: [\"**/target/**\"]  // with untitled:Untitled-1 open\n// after\n// either save the file (file:///.../Untitled-1.rs)\n// or drop excludePatterns so non-file URIs are linted without path conversion","handlingStrategy":"type-guard","validationCode":"function isFilePathDoc(uri) {\n  return uri.startsWith('file:///');\n}","typeGuard":"function shouldSendToHarper(uri, cfg) {\n  const hasPatterns = Array.isArray(cfg?.excludePatterns) && cfg.excludePatterns.length > 0;\n  return !hasPatterns || uri.startsWith('file:///');\n}","tryCatchPattern":"try {\n  await openDocument(uri, text);\n} catch (err) {\n  if (String(err.message).includes('Unable to convert URI to file path')) {\n    // either save the buffer to disk or remove/clear excludePatterns\n  }\n}","preventionTips":["Remember path conversion only happens when excludePatterns is non-empty — clear patterns to lint virtual documents","Save files to disk before opening them with exclusion patterns configured","Keep excludePatterns as a list of string globs against real paths","For remote schemes, run harper-ls where the files live"],"tags":["lsp","uri","filesystem","glob"],"backgroundTag":"invalid-url-format","analyzedSha":"5fe7d5ab76492d83f3ecdbc3f1da83c75dcb6f83","analyzedAt":"2026-09-06T11:34:38.610Z","contentChangedAt":"2026-09-06T11:34:38.610Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}