BoundaryML/baml · error
two targets share subcommand name `{}` (`{}` and `{}`). Subc
Error message
two targets share subcommand name `{}` (`{}` and `{}`). Subcommand names come from the last `.`-segment of the function name; rename one of them so the binary's subcommands stay unambiguous. What it means
resolve_targets checks that every resolved pack target has a unique subcommand name, derived from the last `.`-segment of the function's qualified name (e.g. `user.Foo` and `admin.Foo` both yield `Foo`). If two `-f` targets collide, the packed subcommand binary would have ambiguous subcommands, so the CLI bails naming both full function names.
Source
Thrown at baml_language/crates/baml_cli/src/pack_command.rs:399
/// layer per the spec).
fn resolve_targets(
&self,
engine: &BexEngine,
) -> Result<(baml_exec::PackMode, Vec<ResolvedPackTarget>)> {
if let Some(target) = self.target.as_deref() {
let resolved = resolve_one(engine, target)?;
return Ok((baml_exec::PackMode::Single, vec![resolved]));
}
// Subcommand mode. Resolve each `-f` and reject duplicate subcommand names.
let mut resolved: Vec<ResolvedPackTarget> = Vec::with_capacity(self.functions.len());
for func in &self.functions {
resolved.push(resolve_one(engine, func)?);
}
let mut seen: HashMap<&str, &str> = HashMap::new();
for r in &resolved {
if let Some(prev) = seen.insert(r.subcommand_name.as_str(), r.display_name.as_str()) {
anyhow::bail!(
"two targets share subcommand name `{}` (`{}` and `{}`). \
Subcommand names come from the last `.`-segment of the function name; \
rename one of them so the binary's subcommands stay unambiguous.",
r.subcommand_name,
prev,
r.display_name,
);
}
}
Ok((baml_exec::PackMode::Subcommand, resolved))
}
/// Pick the default output basename.
///
/// - `--file <PATH>` single-file mode: file stem (e.g. `foo.baml` →
/// `foo`). `baml.toml` isn't consulted — single-file packs are
/// intentionally hermetic.
/// - Project mode: `[package].name` from `<from>/baml.toml` when aView on GitHub (pinned to bd85ce9dee)
Solutions
- Rename one of the colliding functions (or move it so its last `.`-segment differs) in the `.baml` source.
- Pack fewer functions — drop one of the colliding `-f` targets.
- Pack each colliding function as a separate single-entry binary using the positional target instead.
Example fix
// before baml pack -f user.Greet -f admin.Greet // after (rename one function in source) baml pack -f user.Greet -f admin.AdminGreet
Defensive patterns
Strategy: validation
Validate before calling
# ensure unique last segments among -f targets
NAMES="user.Greet admin.Greet"
dups=$(echo "$NAMES" | tr ' ' '\n' | awk -F. '{print $NF}' | sort | uniq -d)
[ -n "$dups" ] && { echo "colliding subcommand names: $dups" >&2; exit 2; } Prevention
- Give functions unique final name segments across modules you pack together.
- Check planned `-f` lists for duplicate last segments before packing.
- Prefer distinct top-level names for functions intended as subcommands.
When it happens
Trigger: Running `baml pack -f ns1.MyFunc -f ns2.MyFunc` (or two unqualified names resolving to functions in different modules) where both functions share the same final segment.
Common situations: Packing same-named functions defined in different BAML modules/namespaces; renaming a module without noticing a name collision; auto-generating `-f` lists from scripts that collect qualified names.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- positional `<TARGET>` and `-f/--function` are mutually exclu
- no target specified. Pass a positional `<TARGET>` to pack on
- compilation failed: {e:?}
- no `.baml` files found in {}
- cannot derive an output name from `{}`; pass `-o <PATH>` to
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/8b0b4cc6f74d226d.
Report an issue: GitHub.