aaif-goose/goose · error
invalid thinking effort
Error message
invalid thinking effort
What it means
After the interactive 'Select thinking effort' prompt, the chosen string is parsed with ThinkingEffort::from_str, which accepts off/disabled/none, low, medium/med, high, and max/xhigh. A parse failure is collapsed into this generic message. All menu items (off/low/medium/high/max) are valid variants, so in practice this only fires on menu/enum drift between versions or non-menu input reaching the parse.
Source
Thrown at crates/goose-cli/src/commands/configure.rs:976
};
{
let supports_thinking = match temp_provider.fetch_model_info(&model).await {
Ok(model_info) => model_info.reasoning,
Err(_) => goose_providers::model::ModelConfig::new(&model).is_reasoning_model(),
};
if supports_thinking {
let effort: ThinkingEffort = cliclack::select("Select thinking effort:")
.item("off", "Off - No extended thinking", "")
.item("low", "Low - Better latency, lighter reasoning", "")
.item("medium", "Medium - Moderate thinking", "")
.item("high", "High - Deep reasoning", "")
.item("max", "Max - No constraints on thinking depth", "")
.initial_value("off")
.interact()?
.parse()
.map_err(|_| anyhow::anyhow!("invalid thinking effort"))?;
config.set_goose_thinking_effort(effort)?;
}
}
// Test the configuration
let spin = spinner();
spin.start("Checking your configuration...");
let toolshim_enabled = std::env::var("GOOSE_TOOLSHIM")
.map(|val| val == "1" || val.to_lowercase() == "true")
.unwrap_or(false);
let toolshim_model = std::env::var("GOOSE_TOOLSHIM_OLLAMA_MODEL").ok();
match test_provider_configuration(&provider_name, &model, toolshim_enabled, toolshim_model)
.await
{
Ok(()) => {
goose::config::set_active_provider(config, &provider_name, &model)?;View on GitHub (pinned to 3810898a74)
Solutions
- Re-run `goose configure` and pick one of the offered options (off/low/medium/high/max)
- Update goose so the menu and the ThinkingEffort enum stay in sync
- Embedders: validate candidate strings with ThinkingEffort::from_str before the prompt and surface the parser's own error message
- Set the value directly through configuration instead of the wizard if the option is exposed
Defensive patterns
Strategy: type-guard
Validate before calling
// Rust: validate before the prompt and surface the parser's own message
let raw: String = cliclack::select("Select thinking effort:") /* items */ .interact()?;
let effort: ThinkingEffort = raw.parse().map_err(|e: String| anyhow::anyhow!("{e}"))?; Type guard
fn is_valid_effort(s: &str) -> bool {
matches!(
s.to_lowercase().as_str(),
"off" | "disabled" | "none" | "low" | "medium" | "med" | "high" | "max" | "xhigh"
)
} Prevention
- Generate prompt menus from the enum variants, not hand-listed strings
- Propagate the parser's error text instead of replacing it with a generic one
- Property-test FromStr against every menu item in CI
When it happens
Trigger: A build where the cliclack menu offers a value ThinkingEffort::from_str rejects (menu/enum drift after a patch), or programmatic/expect-driven input feeding an unexpected string to the select prompt.
Common situations: Forked builds that add menu entries without extending the enum; automation driving the configure TUI with scripted stdin; version skew between a wrapper tool and goose.
Related errors
- TLS was requested but no TLS backend is enabled. Enable the
- goose configure requires an interactive terminal. If you ins
- Failed to create provider for OAuth: {}
- Failed to store secret
- --severity: {e}
AI-assisted analysis of aaif-goose/goose@3810898a74 (2026-08-16).
Data as JSON: /api/errors/e977ab5d4f508a98.
Report an issue: GitHub.