Automattic/harper · error · anyhow::Error
Unable to convert URI to file path.
Error message
Unable to convert URI to file path.
What it means
`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."
Source
Thrown at harper-ls/src/backend.rs:272
exclude_patterns,
) = {
let config = self.config.read().await;
(
config.lint_config.clone(),
config.markdown_options,
config.isolate_english,
config.dialect,
config.max_file_length,
config.exclude_patterns.clone(),
)
};
let mut doc_lock = self.doc_state.lock().await;
if !exclude_patterns.is_empty()
&& exclude_patterns.is_match(
uri.to_file_path()
.ok_or_else(|| anyhow!("Unable to convert URI to file path."))?,
)
{
doc_lock.remove(uri);
return Ok(());
}
let ignored_lints = self.load_ignored_lints(uri).await.unwrap_or_default();
let dict = Arc::new(
self.generate_file_dictionary(uri)
.await
.context("Unable to generate the file dictionary.")?,
);
let doc_state = doc_lock.entry(uri.clone()).or_insert_with(|| {
info!("Constructing new LintGroup for new document.");
DocumentState {View on GitHub (pinned to 5fe7d5ab76)
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.
Example fix
// before excludePatterns: ["**/target/**"] // with untitled:Untitled-1 open // after // either save the file (file:///.../Untitled-1.rs) // or drop excludePatterns so non-file URIs are linted without path conversion
Defensive patterns
Strategy: type-guard
Validate before calling
function isFilePathDoc(uri) {
return uri.startsWith('file:///');
} Type guard
function shouldSendToHarper(uri, cfg) {
const hasPatterns = Array.isArray(cfg?.excludePatterns) && cfg.excludePatterns.length > 0;
return !hasPatterns || uri.startsWith('file:///');
} Try / catch
try {
await openDocument(uri, text);
} catch (err) {
if (String(err.message).includes('Unable to convert URI to file path')) {
// either save the buffer to disk or remove/clear excludePatterns
}
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.
Related errors
- Unable to convert URL to file path.
- Unable to convert URI to file path.
- excludePatterns must be an array.
- Unable to save the dictionary to file: {err}
- The code action configuration must be an object.
AI-assisted analysis of Automattic/harper@5fe7d5ab76 (2026-09-06).
Data as JSON: /api/errors/b5bfae7e6931325b.
Report an issue: GitHub.