zed-industries/zed · error · anyhow::Error
capability for process:exec {desired_command} {desired_args:
Error message
capability for process:exec {desired_command} {desired_args:?} is not granted by the extension host What it means
The extension host mediates every process a WASM extension wants to spawn through CapabilityGranter::grant_process_exec. It only allows the call if some `process:exec` capability declared in the extension manifest matches the exact desired command and arguments (per ProcessExecCapability::allows: command must match exactly or be `*`; args must match element-wise, where `*` is a single-arg wildcard and a trailing `**` permits any remaining args). Otherwise it bails with the requested command and args.
Source
Thrown at crates/extension_host/src/capability_granter.rs:41
pub fn grant_exec(
&self,
desired_command: &str,
desired_args: &[impl AsRef<str> + std::fmt::Debug],
) -> Result<()> {
self.manifest.allow_exec(desired_command, desired_args)?;
let is_allowed = self
.granted_capabilities
.iter()
.any(|capability| match capability {
ExtensionCapability::ProcessExec(capability) => {
capability.allows(desired_command, desired_args)
}
_ => false,
});
if !is_allowed {
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!(View on GitHub (pinned to f4178619ac)
Solutions
- Add a matching entry to extension.toml: [[capabilities]] kind = "process:exec" with the exact command and args shown in the error message.
- Use "*" for one wildcard argument and a trailing "**" only when the command legitimately takes arbitrary trailing arguments.
- Rebuild and reinstall/re-test the extension (`zed extension test`) so the updated manifest is loaded.
Example fix
# before: extension.toml has no capabilities section # after [[capabilities]] kind = "process:exec" command = "git" args = ["status", "**"]
Defensive patterns
Strategy: validation
Validate before calling
fn process_exec_allowed(
manifest: &ExtensionManifest,
desired_command: &str,
desired_args: &[&str],
) -> bool {
manifest.capabilities.iter().any(|capability| match capability {
ExtensionCapability::ProcessExec(capability) => {
capability.allows(desired_command, desired_args)
}
_ => false,
})
}
// before spawning from extension code
assert!(process_exec_allowed(&manifest, "git", &["status", "-s"]),
"add a process:exec capability to extension.toml first"); Type guard
fn is_process_exec_capable(capability: &ExtensionCapability) -> bool {
matches!(capability, ExtensionCapability::ProcessExec(_))
} Prevention
- Declare the narrowest args pattern that works; add a trailing "**" only for truly variadic commands.
- Re-run `zed extension test` after every change to subprocess calls or the capabilities list.
- Keep a test that exercises each subprocess call so a manifest regression fails in CI, not in production.
When it happens
Trigger: Extension code invokes a subprocess (e.g. exec of `git status`) while extension.toml has no [[capabilities]] entry with kind = "process:exec", or the declared args no longer match because the code now passes different flags or more arguments than the manifest allows.
Common situations: Adding a new subprocess call or an extra flag to an existing one without updating the manifest allowlist; switching from exact args to variadic args without a trailing "**"; re-publishing an old extension against a host that started enforcing capabilities.
Related errors
- capability for process:exec {desired_command} {desired_args:
- capability for download_file {desired_url} is not granted by
- capability for npm:install {package_name} is not granted by
- mismatched versions: ({}) != ({})
- grammar name '{grammar_name}' must be written in snake_case:
AI-assisted analysis of zed-industries/zed@f4178619ac (2026-08-20).
Data as JSON: /api/errors/b16e5b66fac3c333.
Report an issue: GitHub.