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

no model configured for agent {agent_alias}: [providers.mode

Error message

no model configured for agent {agent_alias}: [providers.models.{provider_name}.<alias>].model is unset and --model was not passed

What it means

In the interactive agent run path, neither the [providers.models.<type>.<alias>].model value nor a --model CLI override produced a model name, so the loop refuses to start. The error is explicit that both sources were checked — set one of them. It differs from the construction-time variant by accepting a CLI rescue.

Source

Thrown at crates/zeroclaw-runtime/src/agent/loop_.rs:1463

                        .with_category(::zeroclaw_log::EventCategory::Agent)
                        .with_outcome(::zeroclaw_log::EventOutcome::Failure)
                        .with_attrs(::serde_json::json!({"agent_alias": agent_alias})),
                    "agent loop refused: agent.model_provider unresolved and no --provider override"
                );
                anyhow::Error::msg(format!(
                    "agents.{agent_alias}.model_provider does not resolve and no provider override \
                     was passed on the CLI. Either set `[agents.{agent_alias}] model_provider` or \
                     pass --provider."
                ))
            })?
            .to_string();

        let mut model_name = match model_override
            .as_deref()
            .or(agent_model_provider.and_then(|e| e.model.as_deref()))
        {
            Some(m) => m.to_string(),
            None => anyhow::bail!(
                "no model configured for agent {agent_alias}: \
             [providers.models.{provider_name}.<alias>].model is unset and --model was not passed"
            ),
        };

        {
            let span = zeroclaw_log::Span::current();
            let mp_composite = match agent_provider_resolved.as_ref() {
                Some((ty, alias, _)) => format!("{ty}.{alias}"),
                None => provider_name.clone(),
            };
            span.record("model_provider", mp_composite.as_str());
            span.record("model", model_name.as_str());
        }

        let agent_runtime_options = match agent_provider_resolved.as_ref() {
            Some((ty, alias, _)) => {
                zeroclaw_providers::provider_runtime_options_for_alias(&config, ty, alias)

View on GitHub (pinned to 88bb9c8533)

Solutions

  1. Pass --model <model-id> on the command line for an immediate unblock.
  2. Or set model = "<model-id>" in the referenced [providers.models.<type>.<alias>] table.
  3. If a wrapper was supposed to supply --model, check it forwards arguments correctly.

Example fix

# before
zeroclaw agent run
# config entry has no model key

# after (either fix works)
zeroclaw agent run --model claude-sonnet-4-5
# or in config:
# [providers.models.anthropic.default]
# model = "claude-sonnet-4-5"
Defensive patterns

Strategy: validation

Validate before calling

// Guard scripts that run on partially configured agents
let model = cfg_model
    .map(str::trim)
    .filter(|m| !m.is_empty())
    .or(cli.model.as_deref());
anyhow::ensure!(model.is_some(), "set providers.models.*.model or pass --model");

Prevention

When it happens

Trigger: Running the agent loop with a provider entry whose model key is unset while omitting --model; a wrapper script that drops the --model argument it was supposed to forward.

Common situations: Testing a freshly added provider entry before choosing a model; scripts that conditionally pass --model and hit the unset branch; config overlays removing the model key.

Related errors


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