{"record":{"id":"d151bbcafe5b334f","repo":"aaif-goose/goose","slug":"provider-has-dynamic-models-false-but-no-sta-d151bb","errorCode":null,"errorMessage":"Provider '{}' has dynamic_models: false but no static models listed; at least one entry in `models` is required.","messagePattern":"Provider '(.+?)' has dynamic_models: false but no static models listed; at least one entry in `models` is required\\.","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/goose-providers/src/ollama.rs","lineNumber":288,"sourceCode":"pub fn from_declarative_config(\n    config: DeclarativeProviderConfig,\n    tls_config: Option<TlsConfig>,\n    key_resolver: impl KeyResolver,\n) -> Result<OllamaProviderBuilder> {\n    let custom_models = if !config.models.is_empty() {\n        Some(\n            config\n                .models\n                .iter()\n                .map(|m| m.name.clone())\n                .collect::<Vec<String>>(),\n        )\n    } else {\n        None\n    };\n\n    if config.dynamic_models == Some(false) && custom_models.is_none() {\n        return Err(anyhow::anyhow!(\n            \"Provider '{}' has dynamic_models: false but no static models listed; \\\n             at least one entry in `models` is required.\",\n            config.name\n        ));\n    }\n\n    let timeout = Duration::from_secs(config.timeout_seconds.unwrap_or(OLLAMA_TIMEOUT));\n\n    let base_has_scheme =\n        config.base_url.starts_with(\"http://\") || config.base_url.starts_with(\"https://\");\n    let base = if base_has_scheme {\n        config.base_url.clone()\n    } else {\n        format!(\"http://{}\", config.base_url)\n    };\n\n    let mut base_url = Url::parse(&base)\n        .map_err(|e| anyhow::anyhow!(\"Invalid base URL '{}': {}\", config.base_url, e))?;","sourceCodeStart":270,"sourceCodeEnd":306,"githubUrl":"https://github.com/aaif-goose/goose/blob/3810898a7447ec3299be72e223d3570a7aabf0ab/crates/goose-providers/src/ollama.rs#L270-L306","documentation":"When building the Ollama provider from a declarative config, goose derives the static model list from the 'models' array (custom_models is None exactly when 'models' is empty) and normally falls back to querying the Ollama /api/tags endpoint for dynamic discovery. Setting \"dynamic_models\": false turns discovery off, so an empty 'models' list would leave the provider with literally no models — this error refuses that contradiction at construction time.","triggerScenarios":"A custom Ollama provider JSON with \"dynamic_models\": false and a missing or empty \"models\": [] array — e.g. someone pinned an Ollama server version and disabled discovery but never listed the models to expose.","commonSituations":"Copying a declarative JSON template where 'models' was pre-cleared for dynamic setups, then flipping dynamic_models to false; intentionally hiding unwanted auto-discovered models but forgetting to enumerate the wanted ones; YAML-to-JSON conversion dropping an empty array field entirely (same effect as empty).","solutions":["List the models you want exposed: \"models\": [{\"name\": \"llama3.2\", \"context_limit\": 131072, \"reasoning\": false}, ...]","Or drop \"dynamic_models\": false entirely — the default discovers models from the running Ollama server","If the goal is filtering, keep dynamic_models on and list models (custom models act as the allowlist) or use skip_canonical_filtering as appropriate"],"exampleFix":"// before\n{ \"name\": \"my-ollama\", \"engine\": \"ollama\", \"base_url\": \"http://localhost:11434\",\n  \"dynamic_models\": false, \"models\": [] }\n\n// after\n{ \"name\": \"my-ollama\", \"engine\": \"ollama\", \"base_url\": \"http://localhost:11434\",\n  \"dynamic_models\": false,\n  \"models\": [{\"name\": \"llama3.2\", \"context_limit\": 131072, \"reasoning\": false}] }","handlingStrategy":"validation","validationCode":"fn ollama_config_valid(cfg: &DeclarativeProviderConfig) -> bool {\n    !(cfg.dynamic_models == Some(false) && cfg.models.is_empty())\n}","typeGuard":null,"tryCatchPattern":"if !ollama_config_valid(&cfg) {\n    return Err(anyhow!(\"'{}' pins models (dynamic_models=false) but lists none; add a models[] entry or drop the flag\", cfg.name));\n}\nollama::from_declarative_config(cfg, tls, resolver)?;","preventionTips":["Treat dynamic_models:false as 'I am declaring the full catalog' — always ship the catalog with it","Template authors: default new Ollama configs to dynamic discovery (omit dynamic_models) until models are enumerated","Add a config lint: dynamic_models=false requires non-empty models[]"],"tags":["ollama","json-config","provider-setup","validation"],"backgroundTag":null,"analyzedSha":"3810898a7447ec3299be72e223d3570a7aabf0ab","analyzedAt":"2026-08-16T10:14:26.282Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}