zeroclaw-labs/zeroclaw · error · anyhow::Error
agents.{agent_alias}.model_provider is empty — set it to a c
Error message
agents.{agent_alias}.model_provider is empty — set it to a configured "<type>.<alias>" (e.g. "anthropic.{agent_alias}") What it means
The process_message twin of the empty model_provider error: on a non-interactive turn, the agent's model_provider is an empty string, which the V3 schema treats as a config error rather than falling back to a default provider. Every agent must name its provider explicitly.
Source
Thrown at crates/zeroclaw-runtime/src/agent/loop_.rs:2913
let observer: Arc<dyn Observer> =
Arc::from(observability::create_observer(&config.observability));
let runtime: Arc<dyn platform::RuntimeAdapter> =
Arc::from(platform::create_runtime(&config.runtime)?);
let security = Arc::new(SecurityPolicy::for_agent(&config, agent_alias)?);
let (provider_name, provider_alias, agent_model_provider) = match config
.resolved_model_provider_for_agent(agent_alias)
{
Some(resolved) => (resolved.0, resolved.1.to_string(), Some(resolved.2.clone())),
None => {
let agent_ref = agent.model_provider.as_str();
if !agent_ref.is_empty() {
anyhow::bail!(
"agents.{agent_alias}.model_provider = \"{agent_ref}\" does not resolve to \
a configured [providers.models.<type>.<alias>] entry"
);
}
anyhow::bail!(
"agents.{agent_alias}.model_provider is empty \u{2014} set it to a configured \
\"<type>.<alias>\" (e.g. \"anthropic.{agent_alias}\")"
);
}
};
let approval_manager = ApprovalManager::for_non_interactive(&risk_profile);
let mem: Arc<dyn Memory> = zeroclaw_memory::create_memory_for_agent(
&config,
agent_alias,
agent_model_provider
.as_ref()
.and_then(|e| e.api_key.as_deref()),
)
.await?;
let (composio_key, composio_entity_id) = if config.composio.enabled {
(
config.composio.api_key.as_deref(),View on GitHub (pinned to 88bb9c8533)
Solutions
- Set model_provider = "<type>.<alias>" on the failing agent (e.g. "anthropic.default").
- Confirm the referenced provider table exists and sets a model.
- Lint all agent tables for non-empty model_provider before reload.
Example fix
# before [agents.telegram-bot] model_provider = "" # after [agents.telegram-bot] model_provider = "anthropic.default"
Defensive patterns
Strategy: validation
Validate before calling
// Lint every agent table before enabling channels/cron
for (alias, agent) in &config.agents {
anyhow::ensure!(
!agent.model_provider.as_str().trim().is_empty(),
"agents.{alias}.model_provider is empty"
);
} Prevention
- Wire model_provider when adding channel-handler agents
- Provisioning templates must fail if the field is unfilled
- Lint config overlays that clear fields
When it happens
Trigger: A channel/cron/gateway turn hits an agent whose model_provider was never set or was blanked by a config edit; provisioning generated an agent table with an empty field.
Common situations: Adding agents for channel handlers without wiring model_provider; config overlays clearing the field; migrating older configs where the field was optional.
Related errors
- 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
- 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/eb520cb0eb48946c.
Report an issue: GitHub.