{"record":{"id":"384b36fada99ef5f","repo":"aaif-goose/goose","slug":"provider-not-set","errorCode":null,"errorMessage":"Provider not set","messagePattern":"Provider not set","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/goose/src/agents/agent.rs","lineNumber":933,"sourceCode":"    ) {\n        for request in &permission_check_result.denied {\n            if let Some(response) = request_to_response_map.get_mut(&request.id) {\n                response.add_tool_response_with_metadata(\n                    request.id.clone(),\n                    Ok(CallToolResult::error(vec![\n                        rmcp::model::ContentBlock::text(DECLINED_RESPONSE),\n                    ])),\n                    request.metadata.as_ref(),\n                );\n            }\n        }\n    }\n\n    /// Get a reference count clone to the provider\n    pub async fn provider(&self) -> Result<Arc<dyn Provider>, anyhow::Error> {\n        match &*self.provider.lock().await {\n            Some(provider) => Ok(Arc::clone(provider)),\n            None => Err(anyhow!(\"Provider not set\")),\n        }\n    }\n\n    /// Resolve the active model config for a session.\n    ///\n    /// The session is the source of truth for the selected model and its\n    /// settings. When the session has no stored config (e.g. before the\n    /// provider has been persisted), fall back to the configured provider\n    /// defaults.\n    pub async fn model_config_for_session(\n        &self,\n        session_id: &str,\n    ) -> Result<goose_providers::model::ModelConfig> {\n        if let Ok(session) = self\n            .config\n            .session_manager\n            .get_session(session_id, false)\n            .await","sourceCodeStart":915,"sourceCodeEnd":951,"githubUrl":"https://github.com/aaif-goose/goose/blob/3810898a7447ec3299be72e223d3570a7aabf0ab/crates/goose/src/agents/agent.rs#L915-L951","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Run `goose configure` (or select a model in the desktop UI) so a provider exists","If embedding, call agent.update_provider(...) right after Agent construction, before any reply/provider() use","Set GOOSE_PROVIDER and GOOSE_MODEL environment variables before starting goose","Pre-check config before starting a session: Config::global().get_goose_provider().is_ok()"],"exampleFix":"// before\nlet agent = Agent::new(config, event_tx);\nlet provider = agent.provider().await?; // Err(\"Provider not set\")\n\n// after\nlet agent = Agent::new(config, event_tx);\nlet provider_name = Config::global().get_goose_provider()?;\nlet model_name = Config::global().get_goose_model()?;\nlet provider = create_provider(&provider_name, &model_name).await?;\nagent.update_provider(Arc::from(provider)).await?;\nlet provider = agent.provider().await?;","handlingStrategy":"validation","validationCode":"fn provider_ready(config: &goose::config::Config) -> bool {\n    config.get_goose_provider().is_ok() && config.get_goose_model().is_ok()\n}\n\n// before first use:\nif !provider_ready(&goose::config::Config::global()) {\n    anyhow::bail!(\"run `goose configure` before starting a session\");\n}","typeGuard":"fn is_provider_not_set(e: &anyhow::Error) -> bool {\n    e.to_string().contains(\"Provider not set\")\n}","tryCatchPattern":"match agent.provider().await {\n    Ok(provider) => provider,\n    Err(e) if is_provider_not_set(&e) => {\n        let provider = bootstrap_provider_from_config().await?;\n        agent.update_provider(provider.into()).await?;\n        agent.provider().await?\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Call update_provider immediately after constructing the Agent","Gate chat/entry points on a completed model selection","Fail fast on missing GOOSE_PROVIDER/GOOSE_MODEL at startup instead of at first provider()"],"tags":["rust","goose","provider","config","initialization"],"backgroundTag":null,"analyzedSha":"3810898a7447ec3299be72e223d3570a7aabf0ab","analyzedAt":"2026-08-16T10:14:26.282Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}