tinyhumansai/openhuman · error

agent `{parent}` ({ptier}) lists `{child}` ({ctier}) in suba

Error message

agent `{parent}` ({ptier}) lists `{child}` ({ctier}) in subagents — {reason}

What it means

Same boot-time validator (loader.rs:433), wrapping a validate_tier_transition failure: the parent's tier may not delegate to the child's tier. Forbidden pairs are Chat→Chat (would defeat the whole point of the fast tier) and Reasoning→Reasoning (depth-blowing recursion of slow models). The pair-rule is the single source of truth shared with the runtime spawn gate in run_subagent, so the definition is rejected at boot with the offending ids and tiers spelled out.

Source

Thrown at src/openhuman/agent/registry/agents/loader.rs:433

                );
            }

            let Some(child_tier) = tier_by_id.get(child_id).copied() else {
                // Unknown id — that's a separate `subagents` integrity
                // concern (covered by existing tests / runtime spawn
                // resolution); don't mask it as a tier error.
                continue;
            };

            // Same-tier delegation is forbidden for chat and reasoning.
            // (Chat→Chat would defeat the whole point of the fast tier;
            // Reasoning→Reasoning produces a depth-blowing recursion of
            // slow models.) The pair-rule lives in `validate_tier_transition`
            // (the single source of truth shared with the runtime spawn gate
            // in `run_subagent`); here we wrap its reason with the offending
            // agent ids + tiers for a boot-time-friendly diagnostic.
            if let Err(reason) = validate_tier_transition(def.agent_tier, child_tier) {
                anyhow::bail!(
                    "agent `{parent}` ({ptier}) lists `{child}` ({ctier}) in subagents — {reason}",
                    parent = def.id,
                    ptier = def.agent_tier.as_str(),
                    child = child_id,
                    ctier = child_tier.as_str(),
                );
            }
        }
    }

    Ok(())
}

/// Parse a single [`BuiltinAgent`] triple into a finished [`AgentDefinition`].
fn parse_builtin(b: &BuiltinAgent) -> Result<AgentDefinition> {
    // The TOML ships without `system_prompt` — serde falls back to
    // `defaults::empty_inline_prompt` — and the loader injects the
    // rendered sibling `prompt.md` immediately below.

View on GitHub (pinned to a221052e0d)

Solutions

  1. Change the child's agent_tier (e.g. make the inner executor a worker) so the transition is allowed
  2. Remove the subagents entry if the delegation is not needed
  3. Move the delegation up a level: let an orchestrator/reasoning parent own both agents instead of chaining same-tier peers
  4. Re-run registry load to confirm a clean boot

Example fix

# before — both tiers are "reasoning"
[agent "reviewer"]
subagents = ["second_reviewer"]

# after — inner agent becomes a worker leaf
[agent "reviewer"]
subagents = []   # or set second_reviewer: agent_tier = "worker"
Defensive patterns

Strategy: validation

Validate before calling

// Same validator catches both worker-leaf and tier-transition violations pre-boot:
openhuman::agent::registry::agents::validate_tier_hierarchy(&defs)?;

Type guard

// Allowed delegation pairs, mirroring validate_tier_transition
fn transition_ok(parent: AgentTier, child: AgentTier) -> bool {
    !matches!((parent, child),
        (AgentTier::Chat, AgentTier::Chat) |
        (AgentTier::Reasoning, AgentTier::Reasoning))
}

Try / catch

// On boot failure, parse out parent/child ids from the message to point at the TOML
if let Err(e) = registry.load() {
    let msg = e.to_string();
    if msg.contains("in subagents") {
        eprintln!("tier-hierarchy violation: {msg}\nChange the child's tier or remove the entry.");
    }
    return Err(e);
}

Prevention

When it happens

Trigger: A chat-tier agent listing another chat-tier agent in subagents; a reasoning-tier agent listing another reasoning-tier agent; adding a new agent to a team and wiring it under a same-tier peer.

Common situations: Building multi-agent teams in TOML with every agent defaulted to the same tier; refactoring agent tiers without re-checking the subagents graph.

Related errors


AI-assisted analysis of tinyhumansai/openhuman@a221052e0d (2026-08-16). Data as JSON: /api/errors/7216bffc4324da7e. Report an issue: GitHub.