{"record":{"id":"9d21b1d18bc1757e","repo":"aaif-goose/goose","slug":"failed-to-unwrap-provider-for-recording","errorCode":null,"errorMessage":"Failed to unwrap provider for recording","messagePattern":"Failed to unwrap provider for recording","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/goose-cli/src/scenario_tests/scenario_runner.rs","lineNumber":300,"sourceCode":"                \"Test replay failed for '{}' ({}) - missing recorded interaction: {}. File deleted - re-run test to record fresh data.\",\n                test_name, factory_name, err_msg\n            ));\n        }\n    }\n\n    let result = ScenarioResult {\n        messages: updated_messages,\n        error,\n    };\n\n    validator(&result)?;\n\n    drop(cli_session);\n\n    if let Some(provider) = provider_for_saving {\n        if result.error.is_none() {\n            Arc::try_unwrap(provider)\n                .map_err(|_| anyhow::anyhow!(\"Failed to unwrap provider for recording\"))?\n                .finish_recording()?;\n        }\n    }\n\n    if let Some(env) = original_env {\n        restore_environment(config, &env);\n    }\n\n    Ok(())\n}\n\nfn setup_environment(config: &ProviderConfig) -> Result<HashMap<&'static str, String>> {\n    let mut original_env = HashMap::new();\n\n    for &var in config.required_env_vars {\n        if let Ok(val) = std::env::var(var) {\n            original_env.insert(var, val);\n        }","sourceCodeStart":282,"sourceCodeEnd":318,"githubUrl":"https://github.com/aaif-goose/goose/blob/3810898a7447ec3299be72e223d3570a7aabf0ab/crates/goose-cli/src/scenario_tests/scenario_runner.rs#L282-L318","documentation":"After a successful recording-mode scenario, Arc::try_unwrap on the provider failed, meaning another clone of the Arc<TestProvider> was still alive when finish_recording() was attempted. drop(cli_session) ran, but some other holder (a leaked session handle, an in-flight task or subagent that captured the provider) keeps the refcount above one. This is an internal lifetime bug in the harness, not a user configuration problem.","triggerScenarios":"A scenario where the CLI session or a spawned subagent/thread retains a clone of the provider Arc past the explicit drop — e.g. background futures not awaited, or session teardown paths that stash the provider elsewhere.","commonSituations":"New agent-loop or session features that keep provider references alive; changes in drop ordering between the legacy loop and the state machine; intermittent depending on task scheduling.","solutions":["Re-run — if failure is scheduling-dependent it may pass, but treat repeats as a real leak.","If developing: audit every Arc::clone of the provider (cli_session, subagents, middleware) and ensure holders are dropped before finish_recording.","File a goose issue with the scenario name and provider; the recording is lost when this trips."],"exampleFix":"// before\ndrop(cli_session);\nArc::try_unwrap(provider)\n    .map_err(|_| anyhow::anyhow!(\"Failed to unwrap provider for recording\"))?;\n\n// after: drop every known holder first, then unwrap\nfor handle in session_handles.drain(..) {\n    handle.shutdown().await;\n}\ndrop(cli_session);\nlet provider = Arc::try_unwrap(provider)\n    .map_err(|_| anyhow::anyhow!(\"provider Arc still shared: {} refs\", Arc::strong_count(&provider)))?;\nprovider.finish_recording()?;","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"if let Err(e) = finish_recording(&provider_arc) {\n    if e.to_string() == \"Failed to unwrap provider for recording\" {\n        // internal leak: report with strong_count diagnostics; recording is lost — rerun to re-record\n        eprintln!(\"provider Arc leak (refs={}), please open an issue\", Arc::strong_count(&provider_arc));\n    }\n}","preventionTips":["Drop every session/subagent handle that cloned the provider Arc before finish_recording.","When adding features that capture the provider, audit Arc clones and their lifetimes."],"tags":["testing","recording","arc-lifetime","concurrency","internal-bug"],"backgroundTag":null,"analyzedSha":"3810898a7447ec3299be72e223d3570a7aabf0ab","analyzedAt":"2026-08-16T10:14:26.282Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}