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

model_provider `{trimmed}` does not resolve to a configured

Error message

model_provider `{trimmed}` does not resolve to a configured provider

What it means

Thrown by model_provider_entry_for_ref when the reference is correctly dotted as `<type>.<alias>` but `config.providers.models.find(provider_type, provider_alias)` returns None — no `[providers.models.<type>.<alias>]` section matches that exact pair. This is the lookup-miss counterpart to the format error (164): the shape is right, the target does not exist.

Source

Thrown at crates/zeroclaw-channels/src/orchestrator/mod.rs:1629

    }
    let (model_provider, _) = model_provider_entry_for_ref(config, configured)?;
    Ok(model_provider)
}

fn model_provider_entry_for_ref<'a>(
    config: &'a Config,
    model_provider: &str,
) -> anyhow::Result<(String, &'a zeroclaw_config::schema::ModelProviderConfig)> {
    let trimmed = model_provider.trim();
    if trimmed.is_empty() {
        anyhow::bail!("model_provider reference must not be empty");
    }

    let Some((provider_type, provider_alias)) = trimmed.split_once('.') else {
        anyhow::bail!("model_provider `{trimmed}` must use `<type>.<alias>` form");
    };
    let Some(entry) = config.providers.models.find(provider_type, provider_alias) else {
        anyhow::bail!("model_provider `{trimmed}` does not resolve to a configured provider");
    };
    Ok((trimmed.to_string(), entry))
}

/// Resolve runtime defaults from `config` against a specific dotted
/// `model_provider` reference (`"<type>.<alias>"`) — the per-agent
/// resolution path.
fn runtime_defaults_from_config(
    config: &Config,
    model_provider: &str,
) -> anyhow::Result<ChannelRuntimeDefaults> {
    let (default_model_provider, entry) = model_provider_entry_for_ref(config, model_provider)?;
    let model = entry
        .model
        .as_deref()
        .map(str::trim)
        .filter(|model| !model.is_empty())
        .map(ToString::to_string)

View on GitHub (pinned to 88bb9c8533)

Solutions

  1. List configured aliases: inspect `[providers.models.<type>]` tables in zeroclaw.toml and note the exact keys
  2. Fix the reference to an existing pair, e.g. `openai.pro` -> `openai.default`
  3. If the alias should exist, add it: `zeroclaw config set providers.models.<type>.<alias>.api_key <key>`

Example fix

# before
[agents.main]
model_provider = "openai.pro"   # only openai.default configured

# after
[agents.main]
model_provider = "openai.default"
Defensive patterns

Strategy: validation

Validate before calling

let (ty, alias) = provider_ref.split_once('.').context("expected `<type>.<alias>`")?;
if config.providers.models.find(ty, alias).is_none() {
    anyhow::bail!("`{provider_ref}` not in [providers.models]; configured: {:?}",
        config.providers.models.aliases_of(ty).collect::<Vec<_>>());
}

Try / catch

Err(err) if err.to_string().contains("does not resolve to a configured provider") => {
    // list available aliases for the family so the operator can correct the ref
}

Prevention

When it happens

Trigger: Resolving refs like `openai.pro` when only `[providers.models.openai.default]` exists; alias typo (`anthropic.prod` vs configured `anthropic.production`); type segment naming a family with no table in config at all. Any caller of model_provider_entry_for_ref, including the agents runtime reload path, produces it.

Common situations: Renaming an alias in zeroclaw.toml without updating agents that reference it; copying an agent stanza between environments whose provider aliases differ; case mismatch — the find is exact, so `OpenAI.default` fails.

Related errors


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