zeroclaw-labs/zeroclaw · error · anyhow::Error

git channel provider `github` requires the `provider-github`

Error message

git channel provider `github` requires the `provider-github` feature

What it means

build_provider selected the github provider, but this build of zeroclaw-channels was compiled without the provider-github cargo feature, so the GitHub implementation is cfg'd out. The channel refuses to start at construction instead of failing later with missing functionality.

Source

Thrown at crates/zeroclaw-channels/src/git/channel.rs:95

fn warn_on_loose_permissions(_path: &str) {}

/// Build the configured forge provider, or a clear error for an unknown
/// `provider` value. The only forge-aware seam in the channel.
fn build_provider(cfg: &GitConfig) -> anyhow::Result<Box<dyn GitProvider>> {
    match cfg.provider.trim().to_ascii_lowercase().as_str() {
        "" | "github" => {
            #[cfg(feature = "provider-github")]
            {
                Ok(Box::new(super::providers::github::GithubProvider::new(
                    cfg.app_id,
                    resolve_github_private_key(cfg)?,
                    cfg.installation_id,
                    cfg.proxy_url.clone(),
                )))
            }
            #[cfg(not(feature = "provider-github"))]
            {
                anyhow::bail!(
                    "git channel provider `github` requires the `provider-github` feature"
                );
            }
        }
        provider @ ("gitea" | "forgejo") => {
            #[cfg(feature = "provider-gitea")]
            {
                // Fail closed before any HTTP client exists: every request
                // attaches `access_token` as a bearer credential, so guessing
                // a default host would send the token to an endpoint the
                // operator never named (e.g. a Forgejo PAT to gitea.com).
                let Some(api_base_url) = cfg
                    .api_base_url
                    .as_deref()
                    .map(str::trim)
                    .filter(|s| !s.is_empty())
                else {
                    anyhow::bail!(

View on GitHub (pinned to 88bb9c8533)

Solutions

  1. Enable the feature where you depend on the crate: zeroclaw-channels = { version = "...", features = ["provider-github"] }
  2. Or use the stock zeroclaw binary, whose feature set already includes the provider
  3. Or switch the channel to a provider that is compiled in (gitea/forgejo need provider-gitea)

Example fix

# before
zeroclaw-channels = { version = "0.7", default-features = false }

# after
zeroclaw-channels = { version = "0.7", default-features = false, features = ["provider-github"] }
Defensive patterns

Strategy: validation

Validate before calling

// Inside a crate that depends on zeroclaw-channels: make the requirement explicit
// zeroclaw-channels = { version = "0.7", features = ["provider-github"] }
// Then guard config at load time:
if cfg.provider == "github" {
    // only reachable if the feature was compiled out of a custom build
    anyhow::bail!("rebuild with --features provider-github or change channels.git.<alias>.provider");
}

Prevention

When it happens

Trigger: channels.git.<alias>.provider = "github" in config while the zeroclaw-channels crate was built without features = ["provider-github"] — e.g. a downstream build using default-features = false or a trimmed distro package.

Common situations: Downstream binaries depending on zeroclaw-channels without enabling its provider features; slim container builds that trim cargo features.

Related errors


AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23). Data as JSON: /api/errors/959dbc008a584680. Report an issue: GitHub.