{"record":{"id":"7d7ee5fa260fcc20","repo":"tinyhumansai/openhuman","slug":"no-providers-available-for-model-probing","errorCode":null,"errorMessage":"No providers available for model probing","messagePattern":"No providers available for model probing","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"src/openhuman/platform/doctor/core.rs","lineNumber":145,"sourceCode":"\n#[derive(Debug, Clone, Serialize, Deserialize)]\npub struct ModelProbeReport {\n    pub entries: Vec<ModelProbeEntry>,\n    pub summary: ModelProbeSummary,\n}\n\nfn doctor_model_targets() -> Vec<String> {\n    crate::openhuman::inference::provider::list_providers()\n        .into_iter()\n        .map(|provider| provider.name.to_string())\n        .collect()\n}\n\npub fn run_models(_config: &Config, _use_cache: bool) -> Result<ModelProbeReport> {\n    let targets = doctor_model_targets();\n\n    if targets.is_empty() {\n        anyhow::bail!(\"No providers available for model probing\");\n    }\n\n    let skipped_count = targets.len();\n    let entries = targets\n        .into_iter()\n        .map(|provider| ModelProbeEntry {\n            provider,\n            outcome: ModelProbeOutcome::Skipped,\n            message: Some(\"model catalog refresh removed\".to_string()),\n        })\n        .collect();\n\n    Ok(ModelProbeReport {\n        entries,\n        summary: ModelProbeSummary {\n            ok: 0,\n            skipped: skipped_count,\n            auth_or_access: 0,","sourceCodeStart":127,"sourceCodeEnd":163,"githubUrl":"https://github.com/tinyhumansai/openhuman/blob/749120085864ce16e0f273c7b86fac7740b39c5b/src/openhuman/platform/doctor/core.rs#L127-L163","documentation":"The doctor's model-probe section builds its target list from inference::provider::list_providers() and bails rather than emitting a vacuous report when that list is empty. In the current code list_providers() returns a fixed single entry (the \"openhuman\" backend), and run_models itself marks every target Skipped with the message \"model catalog refresh removed\" — so this bail is a defensive guard that is effectively unreachable unless the provider registry is emptied by a refactor or trimmed build variant.","triggerScenarios":"Running the doctor models check in a build or fork where list_providers() returns an empty vec — the static list was emptied, the provider module is compiled out by a future gate, or a test stubs the registry to empty.","commonSituations":"Custom forks trimming the provider list; feature-gating experiments around the inference module; test harnesses mocking list_providers.","solutions":["If you forked or trimmed the provider list, restore at least one entry or skip the doctor models section entirely.","Treat the error as a signal that the build's inference surface is empty — verify your feature flags.","For upstream users this indicates a code-state bug, not a config problem — report it rather than working around it."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"if crate::openhuman::inference::provider::list_providers().is_empty() {\n    // nothing to probe — render an empty doctor section instead of calling run_models\n}","typeGuard":null,"tryCatchPattern":"Catch the bail and render the doctor's model section as 'no providers' rather than failing the whole doctor run — the report struct supports an empty entries list.","preventionTips":["Keep doctor sections optional in the UI so one empty section cannot fail the run.","When refactoring the provider registry, add a test asserting list_providers() is non-empty.","Do not gate doctor availability behind provider availability."],"tags":["doctor","inference","diagnostics","providers"],"backgroundTag":"no-providers-configured","analyzedSha":"749120085864ce16e0f273c7b86fac7740b39c5b","analyzedAt":"2026-08-17T21:21:45.363Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}