zeroclaw-labs/zeroclaw · error · anyhow::Error
model_provider `{trimmed}` must use `<type>.<alias>` form
Error message
model_provider `{trimmed}` must use `<type>.<alias>` form What it means
Thrown by model_provider_entry_for_ref when the trimmed provider reference contains no '.' separator, so `split_once('.')` fails. ZeroClaw model providers are addressed as `<type>.<alias>` (e.g. `openai.default`) because each family can hold multiple credentialed aliases under `[providers.models.<type>.<alias>]`; a bare name like `openai` is ambiguous at this layer and is rejected before lookup.
Source
Thrown at crates/zeroclaw-channels/src/orchestrator/mod.rs:1626
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");
};
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()View on GitHub (pinned to 88bb9c8533)
Solutions
- Change the reference to dotted form: `openai` -> `openai.default` (using an alias that exists in config)
- Confirm the alias under `[providers.models.<type>]` in zeroclaw.toml and match it exactly after the dot
- For `/models` chat commands the bare family form is fine — only config fields and programmatic refs require the dot
Example fix
# before [agents.main] model_provider = "openai" # error: model_provider `openai` must use `<type>.<alias>` form # after [agents.main] model_provider = "openai.default"
Defensive patterns
Strategy: validation
Validate before calling
fn is_dotted_provider_ref(s: &str) -> bool {
let t = s.trim();
!t.is_empty() && t.split_once('.').is_some_and(|(a, b)| !a.is_empty() && !b.is_empty())
}
assert!(is_dotted_provider_ref(&agent.model_provider), "must be `<type>.<alias>`"); Type guard
fn is_dotted_provider_ref(s: &str) -> bool {
let t = s.trim();
!t.is_empty()
&& t.split_once('.')
.is_some_and(|(ty, alias)| !ty.is_empty() && !alias.is_empty() && !alias.contains('.'))
} Try / catch
Err(err) if err.to_string().contains("must use `<type>.<alias>` form") => {
// rewrite bare family names to `<family>.default` when that alias exists, else reject
} Prevention
- Encode the dotted form in config schemas/docs examples from day one
- Validate every agent.model_provider with the is_dotted_provider_ref guard at config load
- Reject the value at write time (`zeroclaw config set`) rather than at runtime reload
When it happens
Trigger: Calling model_provider_entry_for_ref (or the runtime reload path that wraps it) with values like `openai`, `anthropic`, or `my provider` — anything without a dot. Note the `/models` chat command tolerates bare family names via resolve_models_command; this stricter dotted-only contract applies to config-file references and programmatic callers.
Common situations: Writing `model_provider = "openai"` in an agent stanza copied from older docs or another tool's style; assuming a default alias is implied; using a colon or slash separator instead of a dot.
Related errors
- model_provider `{ref_or_family}` does not resolve to a confi
- agents.{agent_alias}.model_provider is empty; runtime reload
- model_provider `{trimmed}` does not resolve to a configured
- unknown model_provider `{raw}`
- model_provider reference must not be empty
AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23).
Data as JSON: /api/errors/e82cf17b2d148619.
Report an issue: GitHub.