{"record":{"id":"118b753b5a00ed46","repo":"Hmbown/CodeWhale","slug":"cannot-resume-agent-agent-id-on-its-saved-provider-error","errorCode":null,"errorMessage":"Cannot resume agent {agent_id} on its saved provider '{}': {error}","messagePattern":"Cannot resume agent (.+?) on its saved provider '(.+?)': (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/tools/subagent/mod.rs","lineNumber":6308,"sourceCode":"        if runtime.spawn_depth > runtime.max_spawn_depth {\n            return Err(anyhow!(\n                \"Cannot resume agent {agent_id}: sub-agent depth limit reached (current {}, max {})\",\n                runtime.spawn_depth,\n                runtime.max_spawn_depth\n            ));\n        }\n        runtime.context.workspace = workspace;\n        // Rebind the child's saved provider pin (#6046). The resumed runtime\n        // is derived from the caller, whose active provider can differ from\n        // the provider the child was spawned under; without this rebind the\n        // saved model is validated against the caller's provider and rejected\n        // as a foreign model for a direct provider. `bind_spawn_provider` is\n        // a no-op when the pin already matches, so same-provider children are\n        // unaffected. Borrow the receipt: it is moved into the spawn options\n        // below.\n        if let Some(saved_route) = child_route.as_ref() {\n            bind_spawn_provider(&mut runtime, &saved_route.provider_id).map_err(|error| {\n                anyhow!(\n                    \"Cannot resume agent {agent_id} on its saved provider '{}': {error}\",\n                    saved_route.provider_id\n                )\n            })?;\n        }\n        let saved_manifest = self\n            .worker_records\n            .get(&agent_id)\n            .and_then(|record| record.spec.launch_manifest.as_ref());\n        let options = SubAgentSpawnOptions {\n            name: None, // the old session name stays owned by the terminal record\n            model: Some(model),\n            model_route: None,\n            child_route,\n            nickname: None,\n            fork_context,\n            write_claim: claim.as_ref().map(|(claim, _)| claim.clone()),\n            isolated_worktree: claim","sourceCodeStart":6290,"sourceCodeEnd":6326,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/tools/subagent/mod.rs#L6290-L6326","documentation":"Resume rebinds the child to the provider pinned in its saved spawn route via `bind_spawn_provider`. If that provider is unavailable or cannot be bound (e.g. no direct provider configured for it), resume is rejected with the saved provider id embedded in the message.","triggerScenarios":"Calling agents/resume on an agent whose saved route `provider_id` no longer resolves — `bind_spawn_provider` returns an Err for the saved provider, converted here into this anyhow error.","commonSituations":"Provider was removed or renamed in config since the child spawned; API key for that provider is missing/expired; resume replayed on a machine or profile where only a foreign/direct provider is configured; same-provider children unaffected because the bind is a no-op.","solutions":["Restore or fix the provider named in the error: re-add it to config and ensure its credentials are present.","Check the wrapped `{error}` text from `bind_spawn_provider` for the concrete cause (missing key, unknown provider id).","If the provider is gone for good, abandon resume and re-spawn the child on the now-current provider.","Verify `[subagents]`/model routing config still lists the saved provider id."],"exampleFix":"// before (config)\nproviders: { anthropic: { api_key: \"...\" } }  # saved provider \"openai\" missing\n\n// after\nproviders: { anthropic: { api_key: \"...\" }, openai: { api_key: \"...\" } }","handlingStrategy":"validation","validationCode":"// before resume, verify the saved provider is configured\nlet ok = configured_providers().contains(&saved_route.provider_id)\n    && provider_has_credentials(&saved_route.provider_id);","typeGuard":null,"tryCatchPattern":"match agents.resume(agent_id) {\n    Err(e) if e.to_string().contains(\"on its saved provider\") => {\n        // provider missing/unconfigured: respawn on current provider\n        spawn_new_agent(task, current_provider())\n    }\n    other => other?,\n}","preventionTips":["Keep all providers referenced by active agents configured with valid credentials","Audit provider removals against in-flight/interrupted children","Pin child providers only to providers expected to persist for the session lifetime"],"tags":["subagent","resume","provider","config"],"backgroundTag":"missing-dependency","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-22T11:17:16.035Z"}