AprilNEA/OpenLogi · error
relationship verification failed: fixture case names map to…
Error message
relationship verification failed: fixture case names map to the same file
What it means
While loading a fixture, `load_cassettes` derives the on-disk file name for each declared case (`case_file_name(&case.name)`). Because every case must map to a distinct cassette file, two cases producing the same file name means the manifest is inconsistent; the BTreeMap insert collision triggers this bail. It throws to prevent silently loading one cassette under two manifest entries.
Solutions
- Find the two cases in the manifest whose names collide and rename one so its derived file name is unique
- Remove the genuinely duplicate case entry
- Check the name sanitization (case, spaces, separators) to confirm which names collapse, then pick distinct slugs
Example fix
// before (manifest) cases = ["scroll-up", "scroll up"] // both -> scroll-up.toml // after cases = ["scroll-up", "scroll-down"]
Defensive patterns
Strategy: validation
Validate before calling
# pre-check: manifest case names must derive to unique file names
python3 -c "import sys,collections; names=open('manifest.txt').read().split(); fs=[slug(n) for n in names]; d=[k for k,v in collections.Counter(fs).items() if v>1]; sys.exit(f'duplicate derived names: {d}' and 2)" Try / catch
match load(fixture_dir) {
Err(e) if e.to_string().contains("case names map to the same file") => {
eprintln!("Rename one of the colliding cases in the manifest, then retry.");
Err(e)
}
other => other,
} Prevention
- Use unique, distinct slugs for case names (avoid names differing only by spaces/case/separators)
- After editing the manifest, diff case names against the previous version
- Run `openlogi fixture verify` locally before committing manifest changes
When it happens
Trigger: Declaring two fixture cases in the manifest whose names normalize/escape to the same file name — e.g. `"case one"` and `"case-one"` or `"Case/1"` vs `"case_1"` both collapsing to the same sanitized file name, or literally duplicate case names.
Common situations: Hand-editing the manifest and adding a near-duplicate case name; renaming a case but leaving the old entry; copy-pasting a manifest block without changing the name; a sanitizer that maps distinct names to one slug.
Understand the failure class
Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.
Related errors
- relationship verification failed: profile-only fixture has…
- relationship verification failed: undeclared fixture case…
- relationship verification failed: missing declared fixture…
- relationship verification failed: fixture directory name…
- capture failed with a host, open, disconnect, timeout…
AI-assisted analysis of AprilNEA/OpenLogi@e846e6f4b4 (2026-09-13).
Data as JSON: /api/errors/433cc77d294bba0b.
Report an issue: GitHub.
Appendix: source
Thrown at crates/openlogi-cli/src/cmd/fixture/verify.rs:131
"fixture structure verification failed: fixture directory has no manifest.json",
)?,
profile: profile.context(
"fixture structure verification failed: fixture directory has no profile.json",
)?,
cases,
})
}
}
fn load_cassettes(
cases_directory: Option<&Path>,
manifest: &FixtureManifest,
) -> Result<Vec<HidCassette>> {
let mut expected = BTreeMap::new();
for case in &manifest.cases {
let file_name = case_file_name(&case.name)?;
if expected.insert(file_name, case.name.as_str()).is_some() {
bail!("relationship verification failed: fixture case names map to the same file");
}
}
if expected.is_empty() {
if cases_directory.is_some() {
bail!(
"relationship verification failed: profile-only fixture has an undeclared cases directory"
);
}
return Ok(Vec::new());
}
let directory = cases_directory.context(
"relationship verification failed: manifest declares cases but the cases directory is missing",
)?;
let mut found = BTreeMap::new();
for entry in read_directory(directory, "fixture cases directory")? {
require_regular_file(&entry, "fixture cassette")?;View on GitHub (pinned to e846e6f4b4)