biomejs/biome · error · LspError

failed to convert path to URL: {}

Error message

failed to convert path to URL: {}

What it means

Navigation handlers (go-to-definition, type definitions, references) build the target Location by converting the definition's file path into a file:// URL with Url::from_file_path (navigation.rs:132-138). That conversion fails, and this error is returned, when the path cannot be represented as an absolute file URL - a relative path, an empty path, or on Windows a path without a drive/root prefix.

Source

Thrown at crates/biome_lsp/src/handlers/navigation.rs:134

        let content = session.workspace_for_request().get_file_content(
            biome_service::workspace::GetFileContentParams {
                project_key: doc.project_key,
                path: definition_path.clone(),
            },
        )?;
        let target_line_index = LineIndex::new(&content);
        to_proto::range(&target_line_index, *definition_range, position_encoding)?
    };

    Ok(Location {
        uri: target_uri,
        range: target_range,
    })
}

fn uri_from_path(path: &BiomePath) -> Result<Uri, LspError> {
    let url = url::Url::from_file_path(path.as_path()).map_err(|_| {
        LspError::from(anyhow::anyhow!(
            "failed to convert path to URL: {}",
            path.as_path()
        ))
    })?;
    Uri::from_str(url.as_str())
        .map_err(|err| LspError::from(anyhow::anyhow!("failed to convert URL to URI: {err}")))
}

View on GitHub (pinned to 7529811358)

Solutions

  1. Open files in the editor via absolute file:// URIs (save untitled buffers, avoid synthetic relative paths).
  2. Check that the workspace folder / project root given to the Biome LSP server is an absolute path so internal resolution yields absolute paths.
  3. If the file is a real on-disk file and it still fails, capture the path printed in the error and report it upstream, since daemon-produced paths should always be absolute.

Example fix

// before: opening a document with a relative path
openDocument("src/index.ts");

// after: open with an absolute file:// URI
import { pathToFileURL } from "node:url";
import path from "node:path";
openDocument(pathToFileURL(path.resolve("src/index.ts")).href);
Defensive patterns

Strategy: validation

Validate before calling

// Client-side: always derive document URIs from absolute paths so navigation targets stay absolute
import { pathToFileURL } from "node:url";
import path from "node:path";

function toAbsoluteFileUri(p) {
	const abs = path.isAbsolute(p) ? p : path.resolve(p);
	return pathToFileURL(abs).href; // file:///... always convertible back by the server
}

Try / catch

try {
	const locations = await connection.sendRequest("textDocument/definition", params);
} catch (err) {
	if (String(err?.message ?? err).includes("failed to convert path to URL")) {
		// target resolved to a relative/virtual path; nothing to navigate to
		return [];
	}
	throw err;
}

Prevention

When it happens

Trigger: A navigation target resolves to a relative or empty path, e.g. a synthesized or virtual document with no absolute location; on Windows a path lacking a drive letter. Raised from to_location/uri_from_path while answering a textDocument/definition-style request.

Common situations: Definitions inside in-memory or untitled documents; monorepos or custom workspace roots where the daemon produces a project-relative path; platform-specific path handling differences between Windows and Unix.

Related errors


AI-assisted analysis of biomejs/biome@7529811358 (2026-08-16). Data as JSON: /api/errors/aaf317f73e97f46f. Report an issue: GitHub.