{"record":{"id":"eede2a5c49034c46","repo":"zeroclaw-labs/zeroclaw","slug":"embedding-route-uses-invalid-model-provider","errorCode":null,"errorMessage":"embedding route \"{}\" uses invalid model_provider \"{}\": {}","messagePattern":"embedding route \"(.+?)\" uses invalid model_provider \"(.+?)\": (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"crates/zeroclaw-runtime/src/doctor/mod.rs","lineNumber":1270,"sourceCode":"                    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() {\n            items.push(DiagItem::warn(cat, \"embedding route with empty hint\"));\n        }\n        if let Some(reason) = embedding_provider_validation_error(&route.model_provider) {\n            items.push(DiagItem::warn(\n                cat,\n                format!(\n                    \"embedding route \\\"{}\\\" uses invalid model_provider \\\"{}\\\": {}\",\n                    route.hint, route.model_provider, reason\n                ),\n            ));\n        }\n        if route.model.trim().is_empty() {\n            items.push(DiagItem::warn(\n                cat,\n                format!(\"embedding route \\\"{}\\\" has empty model\", route.hint),\n            ));\n        }\n        if route.dimensions.is_some_and(|value| value == 0) {\n            items.push(DiagItem::warn(\n                cat,\n                format!(\n                    \"embedding route \\\"{}\\\" has invalid dimensions=0\",","sourceCodeStart":1252,"sourceCodeEnd":1288,"githubUrl":"https://github.com/zeroclaw-labs/zeroclaw/blob/88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc/crates/zeroclaw-runtime/src/doctor/mod.rs#L1252-L1288","documentation":"Doctor validates each `embedding_routes.model_provider` against a closed set: `none`, `openai`, or `custom:<url>` where the URL must parse as http/https and be non-empty (embedding_provider_validation_error). Anything else produces this warning with the concrete reason string.","triggerScenarios":"Setting an embedding route's model_provider to a bare name like `openai-large`, an empty `custom:`, `custom:ftp://host`, a custom URL that fails Url::parse, or a provider-table key — none of these are valid embedding provider forms.","commonSituations":"Copy-pasting model-route style provider refs into embedding routes; truncated URLs during templating; scheme typos in custom embedding endpoints.","solutions":["Use one of the accepted forms: `none`, `openai`, or `custom:https://your-endpoint/v1`","For self-hosted embeddings, keep the full http/https URL after `custom:` with no spaces","Re-run `zeroclaw doctor` to confirm the embedding route validates"],"exampleFix":"# before\n[[embedding_routes]]\nhint = \"docs\"\nmodel_provider = \"custom:\"   # empty URL\n\n# after\n[[embedding_routes]]\nhint = \"docs\"\nmodel_provider = \"custom:https://embed.example.com/v1\"","handlingStrategy":"validation","validationCode":"fn embedding_provider_is_valid(name: &str) -> bool {\n    let n = name.trim();\n    n.eq_ignore_ascii_case(\"none\")\n        || n.eq_ignore_ascii_case(\"openai\")\n        || n.strip_prefix(\"custom:\")\n            .map(|u| {\n                matches!(reqwest::Url::parse(u.trim()), Ok(url)\n                    if matches!(url.scheme(), \"http\" | \"https\"))\n            })\n            .unwrap_or(false)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Remember embedding providers use a closed vocabulary (none, openai, custom:<url>) — not provider-table keys","Validate embedding route forms in config linting before deploy"],"tags":["zeroclaw","doctor","config","embedding-routes","provider"],"backgroundTag":"unknown-embedding-provider","analyzedSha":"88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc","analyzedAt":"2026-08-23T01:07:41.857Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}