biomejs/biome · error · anyhow::Error

Failed to parse URI {}: {e}

Error message

Failed to parse URI {}: {e}

What it means

During codeAction/resolve, the Biome LSP server reads back the opaque data blob it originally attached to a code action (CodeActionResolveData with a url field, analysis.rs:381-388) and parses the stored url string into an LSP Uri (analysis.rs:398-401). Because that url is generated by the server itself as the document URI, a parse failure means the blob was corrupted or replaced somewhere in its round trip through the editor client.

Source

Thrown at crates/biome_lsp/src/handlers/analysis.rs:401

    pub url: String,
    pub rule: Option<RuleSelector>,
    pub kind: CodeActionResolveKind,
    pub range: TextRange,
    pub project_key: ProjectKey,
}

fn resolve_code_action_data(data: Option<Value>) -> Result<(CodeActionResolveData, Uri)> {
    let data = data
        .as_ref()
        .context("Missing code action data. This is usually caused by the client not supporting codeAction/resolve.")?;

    let resolve_data: CodeActionResolveData = serde_json::from_value(data.clone())
        .context("Failed to deserialize code action resolve data. This is an internal error, please report it.")?;

    let url: Uri = resolve_data
        .url
        .parse()
        .map_err(|e| anyhow::anyhow!("Failed to parse URI {}: {e}", resolve_data.url))?;

    Ok((resolve_data, url))
}

/// Resolve a code action by computing the actual text edit.
///
/// Called when the user selects a code action from the lightbulb menu.
/// The action's `data` field contains a [`CodeActionResolveData`] token that
/// identifies which rule and action category to compute.
pub(crate) fn code_action_resolve(
    session: &Session,
    params: lsp::CodeAction,
) -> Result<lsp::CodeAction, LspError> {
    let (resolve_data, url) = resolve_code_action_data(params.data.clone())?;

    let path = session.file_path(&url)?;
    let Some(doc) = session.document(&url) else {
        return Err(extension_error(&path).into());

View on GitHub (pinned to 7529811358)

Solutions

  1. Reload the file or restart the editor session so fresh code actions carry server-generated data for the current URIs.
  2. If you implement an LSP client, forward the codeAction object from textDocument/codeAction back to codeAction/resolve byte-for-byte, including data.
  3. Disable any middleware that re-serializes or filters fields inside codeAction.data.
  4. If data round-trips untouched and the error persists, report it to the Biome repository with the URI shown in the message.

Example fix

// before: client rebuilds the action before resolving (url can be corrupted or dropped)
await connection.sendRequest("codeAction/resolve", {
	title: action.title,
	kind: action.kind,
	data: { url: currentFileUri }, // reconstructed, not the original blob
});

// after: client echoes the exact action the server produced
await connection.sendRequest("codeAction/resolve", action);
Defensive patterns

Strategy: validation

Validate before calling

// Client-side: only resolve actions whose data blob is the server's own opaque token
function isResolvableAction(action) {
	return (
		action !== null &&
		typeof action === "object" &&
		typeof action.title === "string" &&
		typeof action.data === "object" &&
		action.data !== null &&
		typeof action.data.url === "string" &&
		action.data.url.length > 0
	);
}

if (isResolvableAction(action)) {
	const resolved = await connection.sendRequest("codeAction/resolve", action);
}

Type guard

type ServerActionData = { url: string; rule?: unknown; kind: string; range: unknown; project_key: number };

function hasServerActionData(action: unknown): action is { title: string; data: ServerActionData } {
	const a = action as { data?: unknown } | null;
	return (
		!!a &&
		typeof a === "object" &&
		!!a.data &&
		typeof (a.data as { url?: unknown }).url === "string" &&
		(a.data as { url: string }).url.length > 0
	);
}

Try / catch

try {
	const resolved = await connection.sendRequest("codeAction/resolve", action);
} catch (err) {
	if (String(err?.message ?? err).includes("Failed to parse URI")) {
		// The action's data is stale or corrupted; re-request code actions for the document instead of retrying.
		const fresh = await connection.sendRequest("textDocument/codeAction", currentParams);
		return fresh;
	}
	throw err;
}

Prevention

When it happens

Trigger: An LSP client that re-serializes, trims, or rebuilds codeAction.data before echoing it in codeAction/resolve; a client resolving a stale code action captured before a workspace/root change, whose url no longer parses; a custom client wrapper constructing the resolve request by hand instead of forwarding the original action object.

Common situations: Custom editor integrations or scripts that call codeAction/resolve directly; stale lightbulb actions after renaming a project or switching workspace folders; a client middleware that normalizes or drops unknown fields inside data.

Understand the failure class

Related errors


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