{"record":{"id":"3398626a01fafad9","repo":"zeroclaw-labs/zeroclaw","slug":"model-route-uses-invalid-model-provider","errorCode":null,"errorMessage":"model route \"{}\" uses invalid model_provider \"{}\": {}","messagePattern":"model route \"(.+?)\" uses invalid model_provider \"(.+?)\": (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"crates/zeroclaw-runtime/src/doctor/mod.rs","lineNumber":1248,"sourceCode":"            items.push(DiagItem::error(cat, \"no model providers configured\"));\n        }\n    }\n\n    // Gateway port range\n    let port = config.gateway.port;\n    if port > 0 {\n        items.push(DiagItem::ok(cat, format!(\"gateway port: {port}\")));\n    } else {\n        items.push(DiagItem::error(cat, \"gateway port is 0 (invalid)\"));\n    }\n\n    // Model routes validation\n    for route in &config.model_routes {\n        if route.hint.is_empty() {\n            items.push(DiagItem::warn(cat, \"model route with empty hint\"));\n        }\n        if let Some(reason) = provider_validation_error(config, &route.model_provider) {\n            items.push(DiagItem::warn(\n                cat,\n                format!(\n                    \"model route \\\"{}\\\" uses invalid model_provider \\\"{}\\\": {}\",\n                    route.hint, route.model_provider, reason\n                ),\n            ));\n        }\n        if route.model.is_empty() {\n            items.push(DiagItem::warn(\n                cat,\n                format!(\"model route \\\"{}\\\" has empty model\", route.hint),\n            ));\n        }\n    }\n\n    // Embedding routes validation\n    for route in &config.embedding_routes {\n        if route.hint.trim().is_empty() {","sourceCodeStart":1230,"sourceCodeEnd":1266,"githubUrl":"https://github.com/zeroclaw-labs/zeroclaw/blob/88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc/crates/zeroclaw-runtime/src/doctor/mod.rs#L1230-L1266","documentation":"`zeroclaw doctor` semantic check walks `model_routes` and tries to instantiate each route's `model_provider` through `create_doctor_model_provider`. When the name does not resolve to a usable provider slot, doctor emits this warning naming the route hint, the offending provider ref, and the first line of the underlying error. It is a diagnostic warning, not a crash.","triggerScenarios":"A `[[model_routes]]` entry whose `model_provider` references a key that is not defined in the providers table (or whose slot is itself invalid); running `zeroclaw doctor` -> check_config_semantics prints the warning.","commonSituations":"Typos in provider names; a provider slot renamed or deleted without updating routes; configs assembled from templates whose route/provider names do not match.","solutions":["Point the route's `model_provider` at an existing provider key from the config's providers table","If the provider is genuinely missing, add the provider slot the route needs","Re-run `zeroclaw doctor` and confirm the warning clears"],"exampleFix":"# before\n[[model_routes]]\nhint = \"cheap\"\nmodel_provider = \"openai-mini\"   # no such provider\n\n# after\n[[model_routes]]\nhint = \"cheap\"\nmodel_provider = \"openai\"        # matches [providers.openai]","handlingStrategy":"validation","validationCode":"let out = std::process::Command::new(\"zeroclaw\")\n    .args([\"doctor\"])\n    .output()?;\nlet text = String::from_utf8_lossy(&out.stdout);\nif text.contains(\"uses invalid model_provider\") {\n    return Err(anyhow::anyhow!(\"config has invalid model_provider refs; fix routes before deploy\"));\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Run `zeroclaw doctor` in CI against the exact config you ship","Rename provider keys with a project-wide search so routes stay in sync","Keep provider names in one place and reference them consistently in routes and agents"],"tags":["zeroclaw","doctor","config","model-routes","provider"],"backgroundTag":"unknown-model-provider","analyzedSha":"88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc","analyzedAt":"2026-08-23T01:07:41.857Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}