AprilNEA/OpenLogi · error
relationship verification failed: undeclared fixture case…
Error message
relationship verification failed: undeclared fixture case file {file_name:?} What it means
When cases are declared, `load_cassettes` reads the cases directory and requires every file present to correspond to a manifest-declared case (looked up by derived file name). Any cassette file that no manifest entry maps to triggers this bail, keeping the fixture free of orphaned cassettes. It throws because loading an undeclared cassette would pair real recorded data with the wrong (or no) case definition.
Solutions
- Delete the orphaned cassette file named in the error from the cases directory
- Or add/rename the corresponding case in the manifest so `case_file_name` matches the existing file
- Sync both sides: after any case rename, rename the cassette file to the newly derived name
Example fix
// before cases/ scroll-up.toml // manifest has only "scroll-down" // after cases/ scroll-up.toml // manifest declares "scroll-up" (and any others present)
Defensive patterns
Strategy: validation
Validate before calling
# pre-check: every cassette file must appear (by derived name) in the manifest for f in fixture-dir/cases/*; do base=$(basename "$f"); grep -q "$(strip_ext "$base")" manifest.txt || echo "orphan cassette: $base"; done
Try / catch
match load(fixture_dir) {
Err(e) if e.to_string().starts_with("relationship verification failed: undeclared fixture case file") => {
let file = extract_file_name(&e); // delete it or declare its case
resolve_orphan(fixture_dir.join(CASES_DIRECTORY).join(file));
load(fixture_dir)
}
other => other,
} Prevention
- Whenever a case is renamed in the manifest, rename its cassette file to match
- Delete cassette files when disabling a case — don't just drop the manifest entry
- Run `openlogi fixture verify` before committing any fixture change
- Avoid copying cassette files between fixtures without updating manifests
When it happens
Trigger: A `.json` cassette file exists in the cases directory but its file name does not match any case name in the manifest — e.g. a case was removed or renamed in the manifest while its cassette file remained, or a cassette was copied in from another fixture.
Common situations: Renaming a case in the manifest without renaming its cassette file (or vice versa); deleting a manifest entry to 'disable' a case instead of deleting the file; merging two fixtures and bringing stray cassettes along; typo in the manifest name changing the derived file name.
Related errors
- relationship verification failed: profile-only fixture has…
- relationship verification failed: missing declared fixture…
- relationship verification failed: fixture directory name…
- fixture structure verification failed: unexpected entry
- relationship verification failed: fixture case names map to…
AI-assisted analysis of AprilNEA/OpenLogi@e846e6f4b4 (2026-09-13).
Data as JSON: /api/errors/7343c1cab9067913.
Report an issue: GitHub.
Appendix: source
Thrown at crates/openlogi-cli/src/cmd/fixture/verify.rs:152
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")?;
let file_name = entry_name(&entry)?;
let Some(case_name) = expected.get(&file_name) else {
bail!("relationship verification failed: undeclared fixture case file {file_name:?}");
};
let cassette: HidCassette = read_json(&entry.path(), "HID cassette")?;
if cassette.name != *case_name {
bail!(
"relationship verification failed: cassette file {file_name:?} contains case {:?}",
cassette.name
);
}
found.insert(file_name, cassette);
}
if let Some(missing) = expected.keys().find(|name| !found.contains_key(*name)) {
bail!("relationship verification failed: missing declared fixture case file {missing:?}");
}
Ok(found.into_values().collect())
}
fn case_file_name(case_name: &str) -> Result<String> {View on GitHub (pinned to e846e6f4b4)