zed-industries/zed · error · anyhow::Error

capability for download_file {desired_url} is not granted by

Error message

capability for download_file {desired_url} is not granted by the extension host

What it means

Before a WASM extension may download a file, the host calls CapabilityGranter::grant_download_file, which requires a `download_file` capability in the manifest whose host and path patterns match the URL (host must match exactly or be `*`; path segments match exactly, `*` for one segment, `**` for everything from that point on, and the pattern must cover the whole path). If no granted capability matches, it bails with the denied URL.

Source

Thrown at crates/extension_host/src/capability_granter.rs:59

            bail!(
                "capability for process:exec {desired_command} {desired_args:?} is not granted by the extension host",
            );
        }

        Ok(())
    }

    pub fn grant_download_file(&self, desired_url: &Url) -> Result<()> {
        let is_allowed = self
            .granted_capabilities
            .iter()
            .any(|capability| match capability {
                ExtensionCapability::DownloadFile(capability) => capability.allows(desired_url),
                _ => false,
            });

        if !is_allowed {
            bail!(
                "capability for download_file {desired_url} is not granted by the extension host",
            );
        }

        Ok(())
    }

    pub fn grant_npm_install_package(&self, package_name: &str) -> Result<()> {
        let is_allowed = self
            .granted_capabilities
            .iter()
            .any(|capability| match capability {
                ExtensionCapability::NpmInstallPackage(capability) => {
                    capability.allows(package_name)
                }
                _ => false,
            });

View on GitHub (pinned to f4178619ac)

Solutions

  1. Compare the URL in the error with the manifest entry; mismatched host is the most common cause (subdomains must be listed separately).
  2. Broaden the path pattern using "**" or add the exact host, e.g. [[capabilities]] kind = "download_file" host = "objects.githubusercontent.com" path = ["**"].
  3. Rebuild/reinstall the extension so the updated manifest takes effect.

Example fix

# before
[[capabilities]]
kind = "download_file"
host = "github.com"
path = ["**"]

# after: also cover GitHub's release-asset CDN
[[capabilities]]
kind = "download_file"
host = "github.com"
path = ["**"]

[[capabilities]]
kind = "download_file"
host = "objects.githubusercontent.com"
path = ["**"]
Defensive patterns

Strategy: validation

Validate before calling

fn download_allowed(manifest: &ExtensionManifest, url: &url::Url) -> bool {
    manifest.capabilities.iter().any(|capability| match capability {
        ExtensionCapability::DownloadFile(capability) => capability.allows(url),
        _ => false,
    })
}

// before fetching in extension code
let url: url::Url = "https://objects.githubusercontent.com/...".parse()?;
assert!(download_allowed(&manifest, &url), "url host/path not covered by a download_file capability");

Type guard

fn is_download_capable(capability: &ExtensionCapability) -> bool {
    matches!(capability, ExtensionCapability::DownloadFile(_))
}

Prevention

When it happens

Trigger: Extension downloads from a URL whose host or path is not covered by any [[capabilities]] kind = "download_file" entry — e.g. the manifest allowlists github.com but code fetches from raw.githubusercontent.com, or the path pattern is shorter than the actual URL path.

Common situations: Adding a second download source (CDN, releases CDN, different subdomain) without extending the allowlist; path patterns like ["specific-owner", "*"] failing on deeper URLs because every segment must be covered; copy-pasted capability entries that don't match the actual fetch URL.

Related errors


AI-assisted analysis of zed-industries/zed@f4178619ac (2026-08-20). Data as JSON: /api/errors/b5588c7d99dc9b84. Report an issue: GitHub.