aaif-goose/goose · error · anyhow::Error
Provider '{}' has dynamic_models: false but no static models
Error message
Provider '{}' has dynamic_models: false but no static models listed; at least one entry in `models` is required. What it means
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.
Source
Thrown at crates/goose-providers/src/ollama.rs:288
pub fn from_declarative_config(
config: DeclarativeProviderConfig,
tls_config: Option<TlsConfig>,
key_resolver: impl KeyResolver,
) -> Result<OllamaProviderBuilder> {
let custom_models = if !config.models.is_empty() {
Some(
config
.models
.iter()
.map(|m| m.name.clone())
.collect::<Vec<String>>(),
)
} else {
None
};
if config.dynamic_models == Some(false) && custom_models.is_none() {
return Err(anyhow::anyhow!(
"Provider '{}' has dynamic_models: false but no static models listed; \
at least one entry in `models` is required.",
config.name
));
}
let timeout = Duration::from_secs(config.timeout_seconds.unwrap_or(OLLAMA_TIMEOUT));
let base_has_scheme =
config.base_url.starts_with("http://") || config.base_url.starts_with("https://");
let base = if base_has_scheme {
config.base_url.clone()
} else {
format!("http://{}", config.base_url)
};
let mut base_url = Url::parse(&base)
.map_err(|e| anyhow::anyhow!("Invalid base URL '{}': {}", config.base_url, e))?;View on GitHub (pinned to 3810898a74)
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
Example fix
// before
{ "name": "my-ollama", "engine": "ollama", "base_url": "http://localhost:11434",
"dynamic_models": false, "models": [] }
// after
{ "name": "my-ollama", "engine": "ollama", "base_url": "http://localhost:11434",
"dynamic_models": false,
"models": [{"name": "llama3.2", "context_limit": 131072, "reasoning": false}] } Defensive patterns
Strategy: validation
Validate before calling
fn ollama_config_valid(cfg: &DeclarativeProviderConfig) -> bool {
!(cfg.dynamic_models == Some(false) && cfg.models.is_empty())
} Try / catch
if !ollama_config_valid(&cfg) {
return Err(anyhow!("'{}' pins models (dynamic_models=false) but lists none; add a models[] entry or drop the flag", cfg.name));
}
ollama::from_declarative_config(cfg, tls, resolver)?; Prevention
- 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[]
When it happens
Trigger: 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.
Common situations: 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).
Related errors
- Invalid provider type: {}
- Failed to parse {}: {}
- Invalid provider id: provider id cannot be empty
- Invalid provider id: {id}
- Invalid base URL '{}': {}
AI-assisted analysis of aaif-goose/goose@3810898a74 (2026-08-16).
Data as JSON: /api/errors/d151bbcafe5b334f.
Report an issue: GitHub.