zeroclaw-labs/zeroclaw · error · anyhow::Error
agents.{agent_alias}.model_provider is empty; runtime reload
Error message
agents.{agent_alias}.model_provider is empty; runtime reload requires a dotted `<type>.<alias>` provider reference What it means
Thrown by resolved_runtime_model_provider_ref when a runtime model reload looks up `config.agents.get(agent_alias)` and finds the agent's `model_provider` field empty after trimming. Runtime reloads need a fully-qualified dotted `<type>.<alias>` reference (e.g. `openai.fast`) to know exactly which credentialed provider entry to rebuild the client from; an empty string cannot be resolved, so the reload aborts rather than guessing a default.
Source
Thrown at crates/zeroclaw-channels/src/orchestrator/mod.rs:1608
)
}
ModelsCommandResolution::Unknown => {
anyhow::bail!("unknown model_provider `{raw}`")
}
}
}
fn resolved_runtime_model_provider_ref(
config: &Config,
agent_alias: &str,
) -> anyhow::Result<String> {
let agent = config
.agents
.get(agent_alias)
.with_context(|| format!("agents.{agent_alias} is not configured"))?;
let configured = agent.model_provider.trim();
if configured.is_empty() {
anyhow::bail!(
"agents.{agent_alias}.model_provider is empty; runtime reload requires a dotted `<type>.<alias>` provider reference"
);
}
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");View on GitHub (pinned to 88bb9c8533)
Solutions
- Set an explicit dotted provider ref on the agent: `zeroclaw config set agents.<agent_alias>.model_provider "openai.default"`
- Verify the `<type>.<alias>` pair actually exists under `[providers.models]` before saving
- Restart or re-trigger the runtime reload; the agent now resolves to a concrete provider entry
Example fix
# before (zeroclaw.toml) [agents.main] model = "gpt-4o" # no model_provider -> reload fails # after [agents.main] model = "gpt-4o" model_provider = "openai.default"
Defensive patterns
Strategy: validation
Validate before calling
let provider_ref = config
.agents
.get(agent_alias)
.map(|a| a.model_provider.trim().to_string())
.filter(|p| !p.is_empty())
.with_context(|| format!("agent `{agent_alias}` needs agents.{agent_alias}.model_provider set"))?; Try / catch
Err(err) if err.to_string().contains("model_provider is empty") => {
// prompt operator to set agents.<alias>.model_provider before retrying reload
} Prevention
- Always set an explicit dotted model_provider on every [agents.*] stanza
- Add a config-lint step at deploy time that fails on agents with empty model_provider
- Treat a missing per-agent provider as a setup error, never fall back silently
When it happens
Trigger: Triggering a runtime model reload for an agent whose `[agents.<alias>]` section exists but has no `model_provider` key (or it is set to "" or whitespace). This happens via the orchestrator's reload path that calls resolved_runtime_model_provider_ref(config, agent_alias).
Common situations: Agent stanza copied from a template that omitted `model_provider`; the field was commented out or blanked during config cleanup; relying on a global default provider and assuming per-agent reload works without an explicit per-agent reference.
Related errors
- model_provider `{ref_or_family}` does not resolve to a confi
- model_provider `{trimmed}` must use `<type>.<alias>` form
- model_provider `{trimmed}` does not resolve to a configured
- start_channels requires at least one enabled [agents.<alias>
- unknown model_provider `{raw}`
AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23).
Data as JSON: /api/errors/6b9ab41293ca7d4d.
Report an issue: GitHub.