Hmbown/CodeWhale · error

Cannot queue a parent message for agent

Error message

Cannot queue a parent message for agent {agent_id}: status is {} (only running children accept messages)

What it means

Parent messages are only accepted by agents whose status is exactly Running. When a resolved agent exists but is in any other state (Completed, Failed, Cancelled, BudgetExhausted, etc.), queueing would silently lose the message, so the library rejects it with this error naming the current status.

Solutions

  1. Check the agent's status before sending and consume its final result instead of queueing more mail.
  2. If follow-up work is needed, spawn a new sub-agent with the additional message.
  3. Add race handling: catch this error and fall back to reading the agent's terminal result.
  4. Adjust orchestration so messages are sent before the child can terminate (e.g. during a wait barrier).

Example fix

// before: unconditional queue
manager.queue_parent_message(&id, text)?;
// after: only queue while running, else read result
match manager.agent_status(&id) {
    SubAgentStatus::Running => manager.queue_parent_message(&id, text)?,
    status => println!("agent done ({status:?}); skipping message"),
}
Defensive patterns

Strategy: validation

Validate before calling

fn accepts_parent_mail(mgr: &SubAgentManager, agent_ref: &str) -> bool {
    mgr.resolve_agent_ref(agent_ref).ok()
        .and_then(|id| mgr.find_agent(&id).map(|a| a.status == SubAgentStatus::Running))
        .unwrap_or(false)
}

Type guard

fn is_running(a: &SubAgent) -> bool { a.status == SubAgentStatus::Running }

Try / catch

match manager.queue_parent_message(&id, text) {
    Err(e) if e.to_string().contains("only running children accept messages") => {
        let result = manager.collect_result(&id)?;
        info!("agent already terminal: {result:?}");
    }
    r => r?,
}

Prevention

When it happens

Trigger: Calling the queue-parent-message API on an agent whose SubAgentStatus is anything other than Running — typically after the child returned its result, failed, was cancelled, or exhausted its budget.

Common situations: A parent sends a follow-up just after the child finished; automation racing agent completion; retry logic re-sending to an agent that already errored out.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22). Data as JSON: /api/errors/8bfee37dee9e277b. Report an issue: GitHub.

Appendix: source

Thrown at crates/tui/src/tools/subagent/mod.rs:5812

        })
    }

    /// Queue-only message entrypoint for live children. Terminal records are
    /// immutable receipts, not mailboxes, so the message surface fails closed
    /// instead of acknowledging undeliverable work.
    pub fn queue_running_parent_message(
        &mut self,
        agent_ref: &str,
        text: String,
    ) -> Result<ParentMailReceipt> {
        let agent_id = self.resolve_agent_ref(agent_ref)?;
        let status = self
            .agents
            .get(&agent_id)
            .map(|agent| agent.status.clone())
            .ok_or_else(|| anyhow!("Agent {agent_id} not found"))?;
        if status != SubAgentStatus::Running {
            return Err(anyhow!(
                "Cannot queue a parent message for agent {agent_id}: status is {} (only running children accept messages)",
                subagent_status_name(&status)
            ));
        }
        self.queue_parent_message(&agent_id, text, false)
    }

    pub(crate) fn queue_running_parent_message_for_session(
        &mut self,
        active_session_id: &str,
        agent_ref: &str,
        text: String,
    ) -> Result<ParentMailReceipt> {
        let agent_id = self.resolve_agent_ref_for_session(active_session_id, agent_ref)?;
        self.queue_running_parent_message(&agent_id, text)
    }

    /// Queue mail and attempt a live wake (`agents/followup`).

View on GitHub (pinned to 73e0f67d83)