{"record":{"id":"be1d374a83dd4594","repo":"aaif-goose/goose","slug":"provider-inventory-refresh-task-panicked","errorCode":null,"errorMessage":"provider inventory refresh task panicked","messagePattern":"provider inventory refresh task panicked","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/goose/src/acp/server/dispatch.rs","lineNumber":240,"sourceCode":"                                        AssertUnwindSafe(async {\n                                            let session_agent =\n                                                agent_bg.get_session_agent(&session_id_bg.0).await?;\n                                            let provider = session_agent\n                                                .provider()\n                                                .await\n                                                .map_err(|e| anyhow::anyhow!(e.to_string()))?;\n                                            let provider_name = provider.get_name().to_string();\n                                            if provider_name != refresh_provider_id {\n                                                return Err(anyhow::anyhow!(\n                                                    \"provider changed before inventory refresh completed\"\n                                                ));\n                                            }\n                                            Ok(provider)\n                                        })\n                                        .catch_unwind()\n                                .await\n                                .map_err(|_| {\n                                    anyhow::anyhow!(\"provider inventory refresh task panicked\")\n                                })\n                                .and_then(|result| result);\n\n                                let fetch_result = match provider_result {\n                                    Ok(provider) => {\n                                        match ensure_refresh_identity_current(\n                                            &refresh_provider_id,\n                                            &refresh_identity,\n                                        )\n                                        .await\n                                        {\n                                            Ok(()) => match AssertUnwindSafe(\n                                                provider.fetch_recommended_models(\n                                                    crate::model_config::global_toolshim(),\n                                                ),\n                                            )\n                                            .catch_unwind()\n                                            .await","sourceCodeStart":222,"sourceCodeEnd":258,"githubUrl":"https://github.com/aaif-goose/goose/blob/3810898a7447ec3299be72e223d3570a7aabf0ab/crates/goose/src/acp/server/dispatch.rs#L222-L258","documentation":"The inventory-refresh task wraps the provider lookup (get_session_agent + provider()) in AssertUnwindSafe(...).catch_unwind(); if that future panicked, the panic is converted into this anyhow error so the background task degrades gracefully instead of tearing down the tokio runtime. The panic itself happened inside session/provider resolution, not in the model fetch.","triggerScenarios":"A panic inside get_session_agent or the provider() call — e.g. a custom provider whose constructor panics, a poisoned or deadlocked lock, or a session that was torn down mid-lookup and unwraps a None.","commonSituations":"Third-party/custom provider implementations that use unwrap/expect on fallible state; sessions being closed concurrently with a refresh; bugs in provider trait implementations.","solutions":["Check the logs for the panic location and backtrace emitted just before this error — it names the real faulting line","Fix or update the provider implementation that panicked (replace unwrap/expect on Option/Result with proper error returns)","Restart the session/agent to clear any poisoned state, then retry the model refresh"],"exampleFix":"// before (provider panics)\nlet cfg = self.config.as_ref().unwrap();\n\n// after\nlet cfg = self\n    .config\n    .as_ref()\n    .ok_or_else(|| anyhow::anyhow!(\"missing provider config\"))?;","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"let provider_result = AssertUnwindSafe(get_provider())\n    .catch_unwind()\n    .await\n    .map_err(|_| anyhow::anyhow!(\"refresh panicked\"));\nif provider_result.is_err() {\n    tracing::error!(\"provider lookup panicked; falling back to last known inventory\");\n}","preventionTips":["Provider trait implementations must not unwrap/expect on fallible state — return Result","Watch logs for the panic site preceding this message; fix it there"],"tags":["panic","provider","inventory","background-task"],"backgroundTag":null,"analyzedSha":"3810898a7447ec3299be72e223d3570a7aabf0ab","analyzedAt":"2026-08-16T10:14:26.282Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}