aaif-goose/goose · error
Failed to unwrap provider for recording
Error message
Failed to unwrap provider for recording
What it means
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.
Source
Thrown at crates/goose-cli/src/scenario_tests/scenario_runner.rs:300
"Test replay failed for '{}' ({}) - missing recorded interaction: {}. File deleted - re-run test to record fresh data.",
test_name, factory_name, err_msg
));
}
}
let result = ScenarioResult {
messages: updated_messages,
error,
};
validator(&result)?;
drop(cli_session);
if let Some(provider) = provider_for_saving {
if result.error.is_none() {
Arc::try_unwrap(provider)
.map_err(|_| anyhow::anyhow!("Failed to unwrap provider for recording"))?
.finish_recording()?;
}
}
if let Some(env) = original_env {
restore_environment(config, &env);
}
Ok(())
}
fn setup_environment(config: &ProviderConfig) -> Result<HashMap<&'static str, String>> {
let mut original_env = HashMap::new();
for &var in config.required_env_vars {
if let Ok(val) = std::env::var(var) {
original_env.insert(var, val);
}View on GitHub (pinned to 3810898a74)
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.
Example fix
// before
drop(cli_session);
Arc::try_unwrap(provider)
.map_err(|_| anyhow::anyhow!("Failed to unwrap provider for recording"))?;
// after: drop every known holder first, then unwrap
for handle in session_handles.drain(..) {
handle.shutdown().await;
}
drop(cli_session);
let provider = Arc::try_unwrap(provider)
.map_err(|_| anyhow::anyhow!("provider Arc still shared: {} refs", Arc::strong_count(&provider)))?;
provider.finish_recording()?; Defensive patterns
Strategy: try-catch
Try / catch
if let Err(e) = finish_recording(&provider_arc) {
if e.to_string() == "Failed to unwrap provider for recording" {
// internal leak: report with strong_count diagnostics; recording is lost — rerun to re-record
eprintln!("provider Arc leak (refs={}), please open an issue", Arc::strong_count(&provider_arc));
}
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Test replay failed for '{}' ({}): {}. File deleted - re-run
- Test replay failed for '{}' ({}) - missing recorded interact
- --concurrency must be at least 1
- Failed to acquire registry lock
- No messages found in scenario result
AI-assisted analysis of aaif-goose/goose@3810898a74 (2026-08-16).
Data as JSON: /api/errors/9d21b1d18bc1757e.
Report an issue: GitHub.