tinyhumansai/openhuman · error

agent ` ` is a `worker` tier and must not list ` ` in its…

Error message

agent `{parent}` is a `worker` tier and must not list `{child}` in its subagents — workers are leaf executors.

What it means

Tier-hierarchy validation in the builtin agent loader: an agent whose agent_tier is worker must not declare any AgentId subagents, because workers are leaf executors with no open-ended spawn surface. The check runs over all loaded definitions including builtins; Skills wildcard entries are exempt since they collapse into a single delegation tool, and unknown child ids are deliberately not masked as tier errors (that is a separate subagents integrity concern).

Solutions

  1. Remove the subagents list from the worker definition, or
  2. change its agent_tier to a tier that is allowed to delegate.
  3. Reload definitions afterwards to confirm the registry validates cleanly.

Example fix

# before
id = "my-worker"
agent_tier = "worker"
[[subagents]]
id = "integrations_agent"

# after (option A: leaf worker)
id = "my-worker"
agent_tier = "worker"
# (no subagents)

# after (option B: delegating tier)
id = "my-worker"
agent_tier = "standard"
Defensive patterns

Strategy: validation

Validate before calling

fn workers_have_no_agent_subagents(defs: &[AgentDefinition]) -> anyhow::Result<()> {
    for def in defs {
        if def.agent_tier == AgentTier::Worker
            && def.subagents.iter().any(|s| matches!(s, SubagentEntry::AgentId(_)))
        {
            anyhow::bail!("worker `{}` lists subagents", def.id);
        }
    }
    Ok(())
}

Prevention

When it happens

Trigger: A custom agent TOML sets agent_tier = "worker" while also listing subagents entries; a builtin's TOML is edited locally to add delegation to a worker-tier agent.

Common situations: Copying an orchestrator-style definition and only changing the tier to worker; authors assuming any agent may delegate.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


AI-assisted analysis of tinyhumansai/openhuman@7491200858 (2026-08-17). Data as JSON: /api/errors/7a6c5b81b33e277e. Report an issue: GitHub.

Appendix: source

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

/// agents that violate the contract fail the boot rather than crashing
/// at spawn time.
pub fn validate_tier_hierarchy(defs: &[AgentDefinition]) -> Result<()> {
    let tier_by_id: HashMap<&str, AgentTier> =
        defs.iter().map(|d| (d.id.as_str(), d.agent_tier)).collect();

    for def in defs {
        for entry in &def.subagents {
            let child_id = match entry {
                SubagentEntry::AgentId(id) => id.as_str(),
                // Workflow wildcards always route to `integrations_agent`
                // (a Worker) via a single collapsed delegation tool —
                // not subject to the tier-mismatch rule.
                SubagentEntry::Skills(_) => continue,
            };

            // Worker leaves: no open-ended spawn surface.
            if def.agent_tier == AgentTier::Worker {
                anyhow::bail!(
                    "agent `{parent}` is a `worker` tier and must not list `{child}` in its \
                     subagents — workers are leaf executors.",
                    parent = def.id,
                    child = child_id,
                );
            }

            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`

View on GitHub (pinned to 7491200858)