{"record":{"id":"d8df3a665096690e","repo":"AprilNEA/OpenLogi","slug":"relationship-verification-failed-profile-only-fixture-has-an","errorCode":null,"errorMessage":"relationship verification failed: profile-only fixture has an undeclared cases directory","messagePattern":"relationship verification failed: profile-only fixture has an undeclared cases directory","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/openlogi-cli/src/cmd/fixture/verify.rs","lineNumber":137,"sourceCode":"        })\n    }\n}\n\nfn load_cassettes(\n    cases_directory: Option<&Path>,\n    manifest: &FixtureManifest,\n) -> Result<Vec<HidCassette>> {\n    let mut expected = BTreeMap::new();\n    for case in &manifest.cases {\n        let file_name = case_file_name(&case.name)?;\n        if expected.insert(file_name, case.name.as_str()).is_some() {\n            bail!(\"relationship verification failed: fixture case names map to the same file\");\n        }\n    }\n\n    if expected.is_empty() {\n        if cases_directory.is_some() {\n            bail!(\n                \"relationship verification failed: profile-only fixture has an undeclared cases directory\"\n            );\n        }\n        return Ok(Vec::new());\n    }\n    let directory = cases_directory.context(\n        \"relationship verification failed: manifest declares cases but the cases directory is missing\",\n    )?;\n\n    let mut found = BTreeMap::new();\n    for entry in read_directory(directory, \"fixture cases directory\")? {\n        require_regular_file(&entry, \"fixture cassette\")?;\n        let file_name = entry_name(&entry)?;\n        let Some(case_name) = expected.get(&file_name) else {\n            bail!(\"relationship verification failed: undeclared fixture case file {file_name:?}\");\n        };\n        let cassette: HidCassette = read_json(&entry.path(), \"HID cassette\")?;\n        if cassette.name != *case_name {","sourceCodeStart":119,"sourceCodeEnd":155,"githubUrl":"https://github.com/AprilNEA/OpenLogi/blob/e846e6f4b4405e33bd6a9aaf949a482ce34cb6d8/crates/openlogi-cli/src/cmd/fixture/verify.rs#L119-L155","documentation":"`load_cassettes` enforces the relationship between the manifest and the fixture layout: a profile-only fixture (no declared cases) must not have a cases directory on disk. If the manifest declares no cases but a cases directory entry was found during inspection, this bail fires. It throws because a cases directory without declared cases indicates a fixture exported in the wrong mode or a manifest that lost its case list.","triggerScenarios":"Verifying/loading a fixture whose manifest has an empty `cases` list while the directory contains a recognized cases-directory entry (CASES_DIRECTORY), i.e. profile-only mode with leftover cassette storage.","commonSituations":"Recording a profile-only fixture over a previous multi-case fixture and the old `cases/` folder was left behind; manually stripping cases from a manifest without deleting the directory; using a profile fixture template that accidentally includes the cases directory.","solutions":["Delete the empty/leftover cases directory from the fixture folder, then re-verify","Or re-add the intended case entries to the manifest if the fixture was never meant to be profile-only","Re-export the fixture with the correct mode (profile vs cases) using the recording tooling"],"exampleFix":"// before\nfixture-dir/\n  manifest.toml        // cases = []\n  cases/               // undeclared for profile-only fixture\n// after\nfixture-dir/\n  manifest.toml        // cases = []","handlingStrategy":"validation","validationCode":"# profile-only fixture must have no cases directory\n[ -d fixture-dir/cases ] && [ ! -s cases-list ] && echo \"remove cases/ or declare cases in the manifest\"","typeGuard":null,"tryCatchPattern":"match load(fixture_dir) {\n    Err(e) if e.to_string().contains(\"profile-only fixture has an undeclared cases directory\") => {\n        remove_dir_all(fixture_dir.join(CASES_DIRECTORY)); // leftover storage\n        load(fixture_dir)\n    }\n    other => other,\n}","preventionTips":["When converting a cases fixture to profile-only, delete the cases directory too","Record profile-only fixtures into a fresh directory instead of overwriting an old one","Run verify after any manual manifest edit"],"tags":["fixture","manifest","verification"],"backgroundTag":"conflicting-config-options","analyzedSha":"e846e6f4b4405e33bd6a9aaf949a482ce34cb6d8","analyzedAt":"2026-09-13T03:07:16.451Z","contentChangedAt":"2026-09-13T03:07:16.451Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}