aaif-goose/goose · error

Provider not set

Error message

Provider not set

What it means

Agent::provider() returns this when the agent's provider slot (self.provider, an Arc<dyn Provider> behind a mutex) is None. The agent is constructed without a provider and one is only installed via update_provider, so any call to provider() before that — directly or indirectly through reply, token counting, or mode updates — fails with this error.

Source

Thrown at crates/goose/src/agents/agent.rs:933

    ) {
        for request in &permission_check_result.denied {
            if let Some(response) = request_to_response_map.get_mut(&request.id) {
                response.add_tool_response_with_metadata(
                    request.id.clone(),
                    Ok(CallToolResult::error(vec![
                        rmcp::model::ContentBlock::text(DECLINED_RESPONSE),
                    ])),
                    request.metadata.as_ref(),
                );
            }
        }
    }

    /// Get a reference count clone to the provider
    pub async fn provider(&self) -> Result<Arc<dyn Provider>, anyhow::Error> {
        match &*self.provider.lock().await {
            Some(provider) => Ok(Arc::clone(provider)),
            None => Err(anyhow!("Provider not set")),
        }
    }

    /// Resolve the active model config for a session.
    ///
    /// The session is the source of truth for the selected model and its
    /// settings. When the session has no stored config (e.g. before the
    /// provider has been persisted), fall back to the configured provider
    /// defaults.
    pub async fn model_config_for_session(
        &self,
        session_id: &str,
    ) -> Result<goose_providers::model::ModelConfig> {
        if let Ok(session) = self
            .config
            .session_manager
            .get_session(session_id, false)
            .await

View on GitHub (pinned to 3810898a74)

Solutions

  1. Run `goose configure` (or select a model in the desktop UI) so a provider exists
  2. If embedding, call agent.update_provider(...) right after Agent construction, before any reply/provider() use
  3. Set GOOSE_PROVIDER and GOOSE_MODEL environment variables before starting goose
  4. Pre-check config before starting a session: Config::global().get_goose_provider().is_ok()

Example fix

// before
let agent = Agent::new(config, event_tx);
let provider = agent.provider().await?; // Err("Provider not set")

// after
let agent = Agent::new(config, event_tx);
let provider_name = Config::global().get_goose_provider()?;
let model_name = Config::global().get_goose_model()?;
let provider = create_provider(&provider_name, &model_name).await?;
agent.update_provider(Arc::from(provider)).await?;
let provider = agent.provider().await?;
Defensive patterns

Strategy: validation

Validate before calling

fn provider_ready(config: &goose::config::Config) -> bool {
    config.get_goose_provider().is_ok() && config.get_goose_model().is_ok()
}

// before first use:
if !provider_ready(&goose::config::Config::global()) {
    anyhow::bail!("run `goose configure` before starting a session");
}

Type guard

fn is_provider_not_set(e: &anyhow::Error) -> bool {
    e.to_string().contains("Provider not set")
}

Try / catch

match agent.provider().await {
    Ok(provider) => provider,
    Err(e) if is_provider_not_set(&e) => {
        let provider = bootstrap_provider_from_config().await?;
        agent.update_provider(provider.into()).await?;
        agent.provider().await?
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Creating an Agent and calling provider() (or an API that calls it) before agent.update_provider(...) has run; building the agent from a Config that has no GOOSE_PROVIDER/GOOSE_MODEL so initialization never resolved a provider.

Common situations: Headless embedding of the goose crate that skips the provider-init step; desktop flows where the user starts chatting before selecting a model; fresh install where `goose configure` was never run; tests that build a bare Agent.

Related errors


AI-assisted analysis of aaif-goose/goose@3810898a74 (2026-08-16). Data as JSON: /api/errors/384b36fada99ef5f. Report an issue: GitHub.