tinyhumansai/openhuman · error

agent registry rejected after merging workspace overrides fr

Error message

agent registry rejected after merging workspace overrides from {}: {}

What it means

AgentDefinitionRegistry::load re-runs `validate_tier_hierarchy` after merging workspace-local TOML overrides (src/openhuman/agent/harness/definition.rs:763) because a workspace file may legally replace a built-in by id but is held to the same spawn contract. The inner error comes from loader.rs:394: either a `worker`-tier agent listing subagents (workers are leaf executors) or a forbidden same-tier delegation via validate_tier_transition (e.g. Chat→Chat or Reasoning→Reasoning in subagents).

Source

Thrown at src/openhuman/agent/harness/definition.rs:763

        let custom = super::definition_loader::load_from_workspace(workspace)?;
        for def in custom {
            tracing::info!(
                id = %def.id,
                source = ?def.source,
                "[agent_defs] loaded custom definition (overrides any built-in with the same id)"
            );
            reg.insert(def);
        }

        // Re-validate the tier hierarchy after custom overrides are
        // merged in — a workspace TOML can legally replace a built-in
        // (same id) and is held to the same spawn-hierarchy contract
        // as the bundled set. See
        // [`crate::openhuman::agent::registry::agents::loader::validate_tier_hierarchy`].
        let snapshot: Vec<AgentDefinition> = reg.list().into_iter().cloned().collect();
        crate::openhuman::agent::registry::agents::validate_tier_hierarchy(&snapshot).map_err(
            |e| {
                anyhow::anyhow!(
                    "agent registry rejected after merging workspace overrides from {}: {}",
                    workspace.display(),
                    e
                )
            },
        )?;

        Ok(reg)
    }

    /// Convenience: resolve the default workspace via
    /// [`crate::openhuman::config::Config::load_or_init`] and load from
    /// it. Built for sync CLI call sites (`openhuman agent list`,
    /// future inspection tools) so they don't re-implement the Config
    /// → workspace resolution dance. Must NOT be called from an
    /// existing tokio runtime — construct a runtime and `block_on`.
    pub async fn load_for_default_workspace() -> Result<Self> {
        let config = crate::openhuman::config::Config::load_or_init().await?;

View on GitHub (pinned to a221052e0d)

Solutions

  1. Read the inner message — it names parent id, parent tier, child id, child tier, and the violated rule.
  2. Remove subagents from worker-tier agents (workers are leaves) or change the parent's tier.
  3. For same-tier delegation, point the subagent entry at a different tier (e.g. a worker) instead of chat→chat / reasoning→reasoning.
  4. Re-run; the registry loads only when the merged set validates.

Example fix

# before: <workspace>/agents/custom.toml
id = "fast_helper"
agent_tier = "worker"
[[subagents]]
id = "docs_worker"        # worker listing subagents -> rejected
# after: drop the subagents block (workers are leaf executors)
id = "fast_helper"
agent_tier = "worker"
Defensive patterns

Strategy: validation

Validate before calling

// Dry-run the exact validation the registry performs, before booting with new overrides:
use crate::openhuman::agent::registry::agents::validate_tier_hierarchy;

let defs = load_definitions_with_overrides(&workspace)?; // your load path
validate_tier_hierarchy(&defs)?; // fails here with the parent/child/tier detail, pre-boot

Try / catch

match AgentDefinitionRegistry::load(&workspace).await {
    Ok(reg) => Ok(reg),
    Err(e) if e.to_string().contains("rejected after merging workspace overrides") => {
        // The inner {e} names parent id+tier and child id+tier.
        // Fix the offending [[subagents]]/tier in the named override file, then reload.
    }
    Err(e) => Err(e),
}

Prevention

When it happens

Trigger: A workspace override defines an agent with `agent_tier = "worker"` plus a `[[subagents]]` entry; or a custom agent at chat tier lists another chat-tier agent as a subagent (reasoning→reasoning equally). Any of these in `<workspace>` agent TOMLs fails the whole registry load at boot/dump time.

Common situations: Users authoring custom agents without knowing the tier contract; upgrading after tier rules tightened, making previously-loading overrides invalid; copying an orchestrator-style TOML for a worker-tier agent.

Related errors


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