tinyhumansai/openhuman · error · anyhow::Error
[chat-factory] no model configured: role '{}' resolved to an
Error message
[chat-factory] no model configured: role '{}' resolved to an empty model id for slug '{}'. Include a model in the provider string (e.g. '{slug}:<model-id>') or set default_model on the cloud_providers entry for slug '{slug}'. What it means
While resolving a cloud provider entry, the effective model id came back empty for a slug whose auth style needs an explicit model (factory.rs:~2185). `OpenhumanJwt` entries are exempt (the managed backend derives the model from `default_model` downstream); for everything else an empty model is fatal. The message names the role and slug and shows the `slug:<model-id>` syntax.
Source
Thrown at src/openhuman/inference/provider/factory.rs:2191
// actionable error. Sending an empty model string to providers like
// nvidia-nim causes a 400 "model field is required" — a confusing error
// that obscures the real cause (missing model in the provider string or
// unset default_model on the config entry).
// See https://github.com/tinyhumansai/openhuman/issues/2784.
//
// OpenhumanJwt entries are exempt: they always delegate to
// make_openhuman_backend which derives the model from config.default_model,
// ignoring whatever effective_model we computed here.
if entry.auth_style != AuthStyle::OpenhumanJwt && effective_model.trim().is_empty() {
log::warn!(
"[nvidia-nim][chat-factory] role={} slug={} resolved to empty model — \
provider string must include a model id (e.g. '{}:<model-id>') or \
set default_model on the cloud_providers entry",
role,
slug,
slug,
);
anyhow::bail!(
"[chat-factory] no model configured: role '{}' resolved to an empty model id for slug '{}'. \
Include a model in the provider string (e.g. '{slug}:<model-id>') or \
set default_model on the cloud_providers entry for slug '{slug}'.",
role,
slug,
);
}
if entry.auth_style != AuthStyle::OpenhumanJwt && is_abstract_tier_model(&effective_model) {
if let Some(default_model) = entry
.default_model
.as_deref()
.map(str::trim)
.filter(|m| !m.is_empty() && !is_abstract_tier_model(m))
{
log::info!(
"[providers][chat-factory] role={} slug={} remapping abstract model {} -> {}",
role,View on GitHub (pinned to 7491200858)
Solutions
- Append the model id to the provider string: `my-slug:<model-id>` (e.g. `deepseek:deepseek-chat`).
- Or set `default_model` on the matching `cloud_providers[]` entry in config so the bare slug resolves.
- Verify with the role named in the message — the fix belongs on that role's provider setting.
- After editing config, retry; resolution runs per request.
Example fix
# config.toml — before chat_provider = "deepseek" # after (either form works) chat_provider = "deepseek:deepseek-chat" # or on the entry: [[cloud_providers]] slug = "deepseek" default_model = "deepseek-chat"
Defensive patterns
Strategy: validation
Validate before calling
// Validate provider strings before they reach the factory:
fn model_id_present(provider: &str, default_model: Option<&str>) -> bool {
provider.contains(':') || default_model.map(str::trim).is_some_and(|m| !m.is_empty())
} Prevention
- Always write provider strings as `slug:<model-id>` unless the entry has `default_model`.
- Validate provider config in a settings lint before saving.
- Remember OpenhumanJwt entries are the only ones allowed to omit the model.
When it happens
Trigger: A provider string like `"deepseek"` with no `:<model-id>` suffix, combined with a `cloud_providers` entry for that slug that has no `default_model`, resolving to an empty effective model for the role.
Common situations: Users add a custom provider slug in Settings but never set a model; a config hand-edit sets `x_provider = "my-slug"` without the model suffix; an entry's `default_model` removed during cleanup.
Related errors
- [chat-factory] model '{}' is an abstract tier for role '{}',
- OPENAI_CODEX_OAUTH_MISSING_AUTH_URL
- Core returned an empty backend URL
- encryption key must decode to 32 raw bytes (raw, base64, or
- memory driver `{driver_id}` does not advertise the `{cap}` c
AI-assisted analysis of tinyhumansai/openhuman@7491200858 (2026-08-17).
Data as JSON: /api/errors/dda9bd29c332d60d.
Report an issue: GitHub.