zeroclaw-labs/zeroclaw · error · anyhow::Error

cli-skills-agent-multiple-bundles

cli-skills-agent-multiple-bundles

Error message

agent '{$alias}' has multiple skill bundles ({$bundles}); pass --bundle to choose one

What it means

When `skills install` has no explicit --bundle, the destination comes from the target agent's assigned bundles — the explicit --agent, else the resolved active agent. If that agent's skill_bundles list holds two or more entries, no single destination can be chosen, so the install aborts naming the agent and its bundles. Only the exactly-one-bundle case auto-targets.

Source

Thrown at src/skills/mod.rs:630

    // 3. Derive the destination from that agent's assigned bundles.
    if let Some(alias) = target_agent.as_deref()
        && let Some(agent_cfg) = config.agent(alias)
    {
        match agent_cfg.skill_bundles.as_slice() {
            [one] => {
                let dir =
                    zeroclaw_config::skill_bundles::resolve_directory(config, &install_root, one)
                        .map_err(anyhow::Error::msg)?;
                return Ok(SkillLocation::Bundle {
                    alias: one.clone(),
                    dir,
                });
            }
            [] => {} // no bundle assigned — fall through to the global dir
            many => {
                let bundles = many.join(", ");
                anyhow::bail!(
                    "{}",
                    get_required_cli_string_with_args(
                        "cli-skills-agent-multiple-bundles",
                        &[("alias", alias), ("bundles", bundles.as_str())],
                    )
                );
            }
        }
    }

    // 4. Global fallback — installed but not auto-loaded (caller prints a note).
    Ok(SkillLocation::Global {
        dir: skills_dir(&config.data_dir),
    })
}

/// Every location (bundle dirs + the global dir) that contains a skill named
/// `name`, as `(label, skill-dir)` pairs. Bundle labels are `bundle:<alias>`;

View on GitHub (pinned to 88bb9c8533)

Solutions

  1. Pass --bundle <alias> to state the destination explicitly
  2. Or trim the agent's skill_bundles list to exactly one entry in config
  3. Or install with no targeting flags so it lands in the global skills dir
  4. Pick the bundle whose skills the agent actually loads at runtime

Example fix

# before
[agents.helper]
skill_bundles = ["work", "personal"]
# `zeroclaw skills install ./s` → error

# after
[agents.helper]
skill_bundles = ["work"]
Defensive patterns

Strategy: validation

Validate before calling

// Before installing without --bundle, ensure the target agent has exactly one bundle
let bundles = config.agent(target_alias).map(|a| a.skill_bundles.clone());
match bundles.as_deref() {
    Some([_one]) => { /* safe: auto-targets that bundle */ }
    Some(many) if many.len() > 1 => eprintln!("pass --bundle; agent has {} bundles", many.len()),
    _ => { /* global fallback */ }
}

Prevention

When it happens

Trigger: An agent configured with skill_bundles = ["work", "personal"] running `skills install <src>` or `--agent <that-agent>`; adding a second bundle to an agent whose installs previously auto-targeted the first.

Common situations: Growing from one shared bundle to per-project bundles; team config templates that pre-assign multiple bundles to each agent.

Related errors


AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23). Data as JSON: /api/errors/ca0554bd830b5090. Report an issue: GitHub.