BoundaryML/baml · error
test selector `{selector}` uses the old `/` hierarchy separa
Error message
test selector `{selector}` uses the old `/` hierarchy separator; use `::` instead (for example `{}`) What it means
A test selector passed to `baml test` mixes `::` column separators with the legacy `/` hierarchy separator. The CLI only accepts `::` for hierarchy; `/` was the old separator. The check fires only for the recognizable legacy shape — an unrooted selector containing both `/` and `::`, no wildcard, and not a canonical `root...` selector (whose test names may legitimately contain a literal `/`).
Source
Thrown at baml_language/crates/baml_cli/src/test_command.rs:244
|| !self.profile_exclude.is_empty()
|| !self.cli_include.is_empty()
|| !self.cli_exclude.is_empty()
}
}
fn validate_selectors<'a>(selectors: impl Iterator<Item = &'a String>) -> Result<()> {
for selector in selectors {
let is_canonical_root =
selector == "root" || selector.starts_with("root.") || selector.starts_with("root::");
// Canonical ids may contain a literal `/` inside a user-provided test
// name. Only diagnose the recognizable legacy shape: an unrooted
// two-column selector whose test tail used `/` for further nesting.
if selector.contains('/')
&& selector.contains("::")
&& !selector.contains('*')
&& !is_canonical_root
{
anyhow::bail!(
"test selector `{selector}` uses the old `/` hierarchy separator; use `::` instead (for example `{}`)",
selector.replace('/', "::")
);
}
}
Ok(())
}
/// Bundle of the engine + tokio runtime + cancellation token shared by every
/// test invocation. Kept as a struct rather than separate arguments so the
/// helper functions don't trip `clippy::too_many_arguments`.
struct RunCtx<'a> {
engine: &'a Arc<BexEngine>,
rt: &'a tokio::runtime::Runtime,
cancel: &'a CancellationToken,
unhandled_spawn_failures: &'a AtomicUsize,
logs: TestLogLevel,
}View on GitHub (pinned to bd85ce9dee)
Solutions
- Replace every `/` with `::` in the selector — the error itself shows the corrected form.
- Update include/exclude patterns in `[test.profiles]` in baml.toml to use `::`.
- Update CI scripts and docs that pass legacy selectors to `baml test`.
- If the `/` is part of a genuine root-rooted test name, root the selector with `root.`/`root::` so it is accepted.
Example fix
// before baml test "my_pkg::Group/SubTest" // after baml test "my_pkg::Group::SubTest"
Defensive patterns
Strategy: validation
Validate before calling
// shell: reject legacy '/' separators in test selectors before invoking
case "$SELECTOR" in
*"/"*) [[ "$SELECTOR" == root* ]] || { echo "use :: not / in '$SELECTOR'"; exit 1; } ;;
esac Try / catch
baml test "$SELECTOR" || { echo "try: ${SELECTOR//\//::}"; exit 1; } Prevention
- Grep baml.toml profiles and CI scripts for selectors containing '/' and migrate them to '::'.
- Prefer copying selectors from current `baml test --list` output over old docs.
- Note the exception: root-rooted selectors may contain '/' inside test names.
When it happens
Trigger: Passing a selector like `pkg::Column/SubTest` to `baml test` (or in profile include/exclude args) where the test-name tail uses `/` for nesting, the selector contains `::`, has no `*`, and doesn't start with `root.`/`root::`.
Common situations: Copy-pasting test IDs from older docs, scripts, or CI configs written before the `::` migration; hand-writing selectors from memory; migrated repos where include/exclude patterns in baml.toml profiles still use `/`.
Understand the failure class
Background: "is deprecated and will be removed" — deprecation warnings for old API names, keywords, and options, and how to migrate before the removal release — this error's family across 29 libraries.
Related errors
- compilation failed: {e:?}
- failed to create engine: {e:?}
- test profile `{name}` was requested, but {} does not exist
- compilation failed: {e:?}
- no `.baml` files found in {}
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/b8fa146659661561.
Report an issue: GitHub.