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

  1. Find the two cases in the manifest whose names collide and rename one so its derived file name is unique
  2. Remove the genuinely duplicate case entry
  3. 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

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


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)