zeroclaw-labs/zeroclaw · error · anyhow::Error
agents.{agent_alias}.model_provider resolves to a model_prov
Error message
agents.{agent_alias}.model_provider resolves to a model_provider entry with no `model` set. Configure [providers.models.{provider_name}.<alias>] model = "...". What it means
On the process_message path, the agent's model_provider resolved to an entry whose model field is unset or blank after trimming, so no model name could be determined for the turn. Same guard as agent construction (agent.rs), re-enforced at message time to catch post-startup config drift.
Source
Thrown at crates/zeroclaw-runtime/src/agent/loop_.rs:3049
);
if count > 0 {
::zeroclaw_log::record!(
INFO,
::zeroclaw_log::Event::new(module_path!(), ::zeroclaw_log::Action::Register)
.with_category(::zeroclaw_log::EventCategory::Channel)
.with_attrs(::serde_json::json!({"count": count})),
&format!("Registered {} channel(s) for process_message agent", count),
);
}
let model_name = match agent_model_provider
.as_ref()
.and_then(|e| e.model.as_deref())
.map(str::trim)
.filter(|m| !m.is_empty())
{
Some(m) => m.to_string(),
None => anyhow::bail!(
"agents.{agent_alias}.model_provider resolves to a model_provider entry with no \
`model` set. Configure [providers.models.{provider_name}.<alias>] model = \"...\"."
),
};
let provider_runtime_options = zeroclaw_providers::provider_runtime_options_for_alias(
&config,
provider_name,
provider_alias.as_str(),
);
let model_provider: Box<dyn ModelProvider> =
zeroclaw_providers::create_routed_model_provider_with_options(
&config,
&format!("{provider_name}.{provider_alias}"),
agent_model_provider
.as_ref()
.and_then(|e| e.api_key.as_deref()),
agent_model_provider.as_ref().and_then(|e| e.uri.as_deref()),
&config.reliability,View on GitHub (pinned to 88bb9c8533)
Solutions
- Set model = "<model-id>" in the named [providers.models.<type>.<alias>] table.
- Restart/reload the runtime so the fixed config takes effect.
- Add a startup check that every resolved entry has a non-empty model.
Example fix
# before [providers.models.openai.main] api_key_env = "OPENAI_API_KEY" # model key absent # after [providers.models.openai.main] api_key_env = "OPENAI_API_KEY" model = "gpt-4o"
Defensive patterns
Strategy: validation
Validate before calling
// Before dispatch: resolved entry must name a model
if let Some((_p, _a, entry)) = config.resolved_model_provider_for_agent(alias) {
anyhow::ensure!(
entry.model.as_deref().map(str::trim).filter(|m| !m.is_empty()).is_some(),
"agent {alias}: provider entry has no model"
);
} Prevention
- Set the model key when the provider table is created
- Re-run config validation after partial deploys
- Restart daemons after fixing the table so the turn path sees the change
When it happens
Trigger: A daemon-driven turn uses an agent whose provider table lost its model key after a reload; an entry configured with auth but model left for later; whitespace-only model value.
Common situations: Partial config deploys; renaming the model key or commenting it out; multi-layer configs where the layer with the model key is not loaded.
Related errors
- no model configured for agent {agent_alias}: [providers.mode
- agents.{agent_alias}.model_provider is empty — set it to a c
- agents.{agent_alias}.model_provider is empty — set it to a c
- agents.{agent_alias}.model_provider resolves to a model_prov
- agents.{agent_alias}.model_provider = "{agent_ref}" does not
AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23).
Data as JSON: /api/errors/c82cf9117051eef5.
Report an issue: GitHub.