{"record":{"id":"dfd9e54d9784bf15","repo":"Hmbown/CodeWhale","slug":"calling-agent-not-found","errorCode":null,"errorMessage":"Calling agent not found","messagePattern":"Calling agent not found","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/tui/src/tools/subagent/mod.rs","lineNumber":7560,"sourceCode":"        agent_ref: &str,\n        caller_agent_id: Option<&str>,\n        action: &str,\n    ) -> Result<String> {\n        let agent_id = self.resolve_agent_ref(agent_ref)?;\n        let Some(caller) = caller_agent_id\n            .map(str::trim)\n            .filter(|caller| !caller.is_empty() && *caller != \"root\")\n        else {\n            return Ok(agent_id);\n        };\n        let caller_identity = if self.agents.contains_key(caller) {\n            self.continuation_target(caller)?\n        } else {\n            // Internal headless parents can own a worker record without a\n            // paired SubAgent projection. A missing caller still fails closed.\n            self.worker_record_by_ref(caller)\n                .map(|(id, _)| id)\n                .ok_or_else(|| anyhow!(\"Calling agent not found\"))?\n        };\n        if caller_identity == self.continuation_target(&agent_id)? {\n            return Err(anyhow!(\n                \"Refusing {action} on self (agent_id '{agent_id}'); child coordination authority is limited to strict descendants.\"\n            ));\n        }\n\n        let mut cursor = agent_id.clone();\n        let mut visited = std::collections::HashSet::new();\n        while visited.insert(cursor.clone()) {\n            let Some((_, record)) = self.worker_record_by_ref(&cursor) else {\n                break;\n            };\n            let Some(parent_ref) = record\n                .parent_run_id\n                .as_deref()\n                .or(record.spec.parent_run_id.as_deref())\n            else {","sourceCodeStart":7542,"sourceCodeEnd":7578,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/tools/subagent/mod.rs#L7542-L7578","documentation":"Authority checks for subagent coordination require the calling agent's identity. Internal headless parents can own a worker record without a paired SubAgent projection, and when even the worker record lookup fails the check fails closed with this error because the caller's identity cannot be established.","triggerScenarios":"A coordination tool call (control/send/interrupt) where `caller` resolves neither to a continuation target SubAgent nor to a worker record — e.g. an unknown or already-removed caller ref passed by the engine or a stale record after cleanup.","commonSituations":"A caller agent being reaped mid-operation; a corrupted or manually edited subagent state directory dropping the worker record; engine passing an obsolete caller ref after session restart.","solutions":["Re-open or re-derive the subagent session so caller records are rebuilt from the authoritative state","Check the subagent state root for a deleted/corrupt worker record and restore or re-spawn the parent","Retry after the current operation finishes — the caller may have been a transient headless parent"],"exampleFix":"// before\nlet caller_id = self.worker_record_by_ref(caller).map(|(id,_)| id).ok_or_else(|| anyhow!(\"Calling agent not found\"))?;\n// after (caller side)\nif !self.has_agent(caller) { return Ok(Status::caller_gone); } // handle missing caller before invoking the control tool","handlingStrategy":"try-catch","validationCode":"fn caller_is_known(state: &SubAgentState, caller: &str) -> bool {\n    state.worker_records.iter().any(|r| r.ref_name == caller) || state.agents.iter().any(|a| a.id == caller)\n}","typeGuard":"fn has_worker_record(state: &SubAgentState, caller: &str) -> bool {\n    state.worker_records.iter().any(|r| r.ref_name == caller)\n}","tryCatchPattern":"match ensure_caller_authority(state, caller, target) {\n    Err(e) if e.to_string() == \"Calling agent not found\" => {\n        // caller record vanished; rebuild state from disk or abort the coordination op gracefully\n        rebuild_state_and_retry_or_abort()\n    }\n    Err(e) => return Err(e),\n    Ok(()) => proceed(),\n}","preventionTips":["Don't delete or hand-edit files under the subagent state root while a session is live","Verify the caller is still active before issuing coordination commands","Re-derive caller refs from the current session after any restart"],"tags":["subagent","rust","authority"],"backgroundTag":"entity-not-found","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-22T16:17:23.217Z"}