{"record":{"id":"03b75efea648ba80","repo":"Zackriya-Solutions/meetily","slug":"at-least-one-model-must-be-defined","errorCode":null,"errorMessage":"At least one model must be defined","messagePattern":"At least one model must be defined","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"frontend/src-tauri/src/summary/summary_engine/models.rs","lineNumber":231,"sourceCode":"            context_size: 32768,\n            layer_count: 26,\n            sampling: SamplingParams::gemma3_instruct(vec![\"<end_of_turn>\".to_string()]),\n            description: \"Fastest model. Runs on any hardware with ~1GB RAM. Good for quick summaries.\".to_string(),\n        },\n    ]\n}\n\n/// Get a specific model by name\npub fn get_model_by_name(name: &str) -> Option<ModelDef> {\n    get_available_models().into_iter().find(|m| m.name == name)\n}\n\n/// Get the default model (first in list)\npub fn get_default_model() -> ModelDef {\n    get_available_models()\n        .into_iter()\n        .next()\n        .expect(\"At least one model must be defined\")\n}\n\n/// Resolve model name to full file path in the models directory\npub fn get_model_path(app_data_dir: &PathBuf, model_name: &str) -> Result<PathBuf> {\n    let model = get_model_by_name(model_name)\n        .ok_or_else(|| anyhow!(\"Unknown model: {}\", model_name))?;\n\n    let models_dir = get_models_directory(app_data_dir);\n    let model_path = models_dir.join(&model.gguf_file);\n\n    Ok(model_path)\n}\n\n/// Get the models directory path for built-in AI\npub fn get_models_directory(app_data_dir: &PathBuf) -> PathBuf {\n    app_data_dir.join(\"models\").join(\"summary\")\n}\n","sourceCodeStart":213,"sourceCodeEnd":249,"githubUrl":"https://github.com/Zackriya-Solutions/meetily/blob/0281737d87d26352fb0adc78c8c0975f691b23d1/frontend/src-tauri/src/summary/summary_engine/models.rs#L213-L249","documentation":"get_default_model takes the first element of get_available_models() and expects the list non-empty. The catalog is a hard-coded Vec of four GGUF models, so with the current code this cannot fail; the expect becomes live the moment the catalog turns dynamic (feature-gated builds, runtime config, user filtering) and yields zero entries.","triggerScenarios":"Refactoring get_available_models to read from config or feature flags and returning an empty Vec (e.g. a slim build with all downloadable models gated off), or filtering the list by user settings that exclude everything before calling get_default_model.","commonSituations":"Slim/no-network build variants, unit tests constructing empty catalogs, catalog refactors that forget a fallback entry.","solutions":["Add a unit test asserting !get_available_models().is_empty() so the invariant is checked in CI","Change the signature to Result<ModelDef> (anyhow \"model catalog is empty\") and propagate to callers","If kept panic-free, guarantee a fallback entry at compile time (const-assert the literal list length > 0)"],"exampleFix":"// before\npub fn get_default_model() -> ModelDef {\n    get_available_models().into_iter().next()\n        .expect(\"At least one model must be defined\")\n}\n\n// after\npub fn get_default_model() -> anyhow::Result<ModelDef> {\n    get_available_models().into_iter().next()\n        .ok_or_else(|| anyhow::anyhow!(\"model catalog is empty\"))\n}\n\n#[test]\nfn catalog_never_empty() {\n    assert!(!get_available_models().is_empty());\n}","handlingStrategy":"validation","validationCode":"#[test]\ndefault_model_exists() {\n    assert!(!summary_engine::models::get_available_models().is_empty());\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["If the catalog ever becomes dynamic, switch get_default_model to Result and propagate","Pin the invariant with a unit test that fails when the catalog is emptied","When feature-gating models, always keep one unconditional fallback entry"],"tags":["rust","model-catalog","invariant","gguf","llama-cpp"],"backgroundTag":"empty-model-catalog","analyzedSha":"0281737d87d26352fb0adc78c8c0975f691b23d1","analyzedAt":"2026-08-16T20:57:52.567Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}