{"record":{"id":"4759a881e6d218aa","repo":"tinyhumansai/openhuman","slug":"chat-factory-model-is-an-abstract-tier-for","errorCode":null,"errorMessage":"[chat-factory] model '{}' is an abstract tier for role '{}', but cloud provider slug '{}' has no concrete default_model configured. Set cloud_providers[].default_model to a provider-native model id (e.g. deepseek-v4-pro).","messagePattern":"\\[chat-factory\\] model '(.+?)' is an abstract tier for role '(.+?)', but cloud provider slug '(.+?)' has no concrete default_model configured\\. Set cloud_providers\\[\\]\\.default_model to a provider-native model id \\(e\\.g\\. deepseek-v4-pro\\)\\.","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"src/openhuman/inference/provider/factory.rs","lineNumber":2216,"sourceCode":"    }\n\n    if entry.auth_style != AuthStyle::OpenhumanJwt && is_abstract_tier_model(&effective_model) {\n        if let Some(default_model) = entry\n            .default_model\n            .as_deref()\n            .map(str::trim)\n            .filter(|m| !m.is_empty() && !is_abstract_tier_model(m))\n        {\n            log::info!(\n                \"[providers][chat-factory] role={} slug={} remapping abstract model {} -> {}\",\n                role,\n                slug,\n                effective_model,\n                default_model\n            );\n            effective_model = default_model.to_string();\n        } else {\n            anyhow::bail!(\n                \"[chat-factory] model '{}' is an abstract tier for role '{}', \\\n                 but cloud provider slug '{}' has no concrete default_model configured. \\\n                 Set cloud_providers[].default_model to a provider-native model id (e.g. deepseek-v4-pro).\",\n                effective_model,\n                role,\n                slug\n            );\n        }\n    }\n\n    log::info!(\n        \"[providers][chat-factory] role={} slug={} model={} endpoint_host={}\",\n        role,\n        slug,\n        effective_model,\n        redact_endpoint(&entry.endpoint)\n    );\n","sourceCodeStart":2198,"sourceCodeEnd":2234,"githubUrl":"https://github.com/tinyhumansai/openhuman/blob/749120085864ce16e0f273c7b86fac7740b39c5b/src/openhuman/inference/provider/factory.rs#L2198-L2234","documentation":"The effective model for a role resolved to an abstract tier name (something `is_abstract_tier_model` recognizes, e.g. a tier like 'fast'/'balanced' rather than a provider-native model id). The factory tried to remap it to a concrete model via the entry's `default_model`, but that field is missing or itself abstract/blank, so it bails (factory.rs:~2205-2216).","triggerScenarios":"A role configured with an abstract tier model (e.g. `fast`, `quality`) on a custom `cloud_providers` slug whose entry lacks a concrete `default_model`, or whose `default_model` is another abstract tier rather than a real model id like `deepseek-v4-pro`.","commonSituations":"Copying a provider config from the managed backend (where tiers are valid) to a BYOK slug (where they are not); setting `default_model = \"fast\"` by mistake; deleting the `default_model` line while editing an entry.","solutions":["Set `cloud_providers[].default_model` to a provider-native model id, e.g. `deepseek-v4-pro`.","Or bypass the tier entirely: put a concrete model in the provider string (`slug:<concrete-model>`).","Check the entry with the slug named in the message — the fix is scoped to that entry.","Retry the request after saving config."],"exampleFix":"# config.toml — before\n[[cloud_providers]]\nslug = \"deepseek\"\ndefault_model = \"fast\"\n\n# after\n[[cloud_providers]]\nslug = \"deepseek\"\ndefault_model = \"deepseek-v4-pro\"","handlingStrategy":"validation","validationCode":"fn concrete_model_configured(entry: &CloudProviderEntry, effective_model: &str) -> bool {\n    if !is_abstract_tier_model(effective_model) { return true; }\n    entry.default_model.as_deref()\n        .map(|m| !m.trim().is_empty() && !is_abstract_tier_model(m))\n        .unwrap_or(false)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never copy tier names ('fast', 'quality') into BYOK entries — use provider-native model ids.","When a settings UI offers tiers for custom slugs, map them to concrete defaults on save.","Lint `default_model` values to reject abstract tier strings."],"tags":["config","abstract-tier","default-model","factory"],"backgroundTag":"missing-model-id","analyzedSha":"749120085864ce16e0f273c7b86fac7740b39c5b","analyzedAt":"2026-08-17T21:21:45.363Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}