{"record":{"id":"27b6a30051316e7b","repo":"AprilNEA/OpenLogi","slug":"the-selected-device-has-no-stable-synthetic-identity-for","errorCode":null,"errorMessage":"the selected device has no stable synthetic identity for cassette relationships; rerun with --profile-only","messagePattern":"the selected device has no stable synthetic identity for cassette relationships; rerun with --profile-only","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/openlogi-cli/src/cmd/fixture/contribute.rs","lineNumber":379,"sourceCode":"    route: &DeviceRoute,\n    slot: u8,\n) -> Result<&'a DeviceModelInfo> {\n    profile\n        .inventories\n        .iter()\n        .find(|inventory| {\n            inventory.paired.iter().any(|device| {\n                DeviceRoute::device_route_for(inventory, device.slot).as_ref() == Some(route)\n            })\n        })\n        .and_then(|inventory| inventory.paired.iter().find(|device| device.slot == slot))\n        .and_then(|device| device.model_info.as_ref())\n        .ok_or_else(|| anyhow!(\"selected profile route has no identity-bearing device model\"))\n}\n\nfn add_model_identities(plan: &mut HidCassetteIdentityPlan, model: &DeviceModelInfo) -> Result<()> {\n    if model.unit_id == [0; 4] && model.serial_number.is_none() {\n        bail!(\n            \"the selected device has no stable synthetic identity for cassette relationships; \\\n             rerun with --profile-only\"\n        );\n    }\n    if model.unit_id != [0; 4] {\n        plan.insert(SanitizedIdentityKind::DeviceUnitId, model.unit_id.to_vec())?;\n    }\n    if let Some(serial) = model.serial_number.as_deref() {\n        plan.insert(\n            SanitizedIdentityKind::DeviceSerialNumber,\n            serial.as_bytes().to_vec(),\n        )?;\n    }\n    Ok(())\n}\n\nfn require_same_structural_route(expected: &DeviceRoute, actual: &DeviceRoute) -> Result<()> {\n    let matches = match (expected, actual) {","sourceCodeStart":361,"sourceCodeEnd":397,"githubUrl":"https://github.com/AprilNEA/OpenLogi/blob/e846e6f4b4405e33bd6a9aaf949a482ce34cb6d8/crates/openlogi-cli/src/cmd/fixture/contribute.rs#L361-L397","documentation":"Cassette files record sanitized identity material (device unit ID and/or serial number) so relationships between cassettes can be verified. `add_model_identities` refuses to proceed when the selected device's `DeviceModelInfo` has an all-zero unit ID and no serial number, because there is no stable identity to anchor cassette relationships; it suggests rerunning with `--profile-only`, which omits cassette capture.","triggerScenarios":"Running a full `openlogi fixture contribute` capture when the selected device model reports `unit_id == [0;4]` and `serial_number == None` — e.g. a device that failed identity probing, a cloned/anonymous unit, or a profile snapshot taken before the device reported its identity.","commonSituations":"Devices whose HID++ identity probe returned zeros (firmware quirk or probe failure); fixtures built from stale profiles captured before a firmware update changed identity reporting; contributing from a mock/test device without identity data; selecting a slot whose device lacks model_info identity fields.","solutions":["Rerun with `--profile-only` as the error suggests — this is the supported mode when no stable identity exists","Re-capture the device profile so the unit ID/serial probe runs again and identity fields are populated","Verify on hardware (`openlogi list` / diagnostics) that the device actually reports a non-zero unit ID or serial; if it never does, the device cannot anchor cassette relationships","Pick a different device/slot that reports stable identity if multiple devices are available"],"exampleFix":"// before: full cassette capture with an identity-less device\n$ openlogi fixture contribute --id my-fixture --device 1 --output output/my-fixture\nError: the selected device has no stable synthetic identity for cassette relationships; rerun with --profile-only\n// after\n$ openlogi fixture contribute --id my-fixture --device 1 --output output/my-fixture --profile-only","handlingStrategy":"validation","validationCode":"// Before a full capture, confirm the selected model has stable identity\nfn has_stable_identity(model: &DeviceModelInfo) -> bool {\n    model.unit_id != [0; 4] || model.serial_number.is_some()\n}\nif !has_stable_identity(&model) {\n    eprintln!(\"no stable identity: use --profile-only\");\n}","typeGuard":"fn is_cassette_capable(model: &DeviceModelInfo) -> bool {\n    model.unit_id != [0; 4] || model.serial_number.is_some()\n}","tryCatchPattern":"match contribute_result {\n    Err(e) if e.to_string().contains(\"no stable synthetic identity\") => {\n        eprintln!(\"falling back to --profile-only\");\n        // rerun with args.profile_only = true\n    }\n    other => other?,\n}","preventionTips":["Inspect the captured profile's model_info for a non-zero unit_id or serial before attempting full capture","Re-probe the device (re-capture the profile) if identity fields come back zeroed","Prefer devices that report serial numbers for cassette contributions","Fall back to `--profile-only` automatically when identity fields are absent"],"tags":["fixtures","hid","identity","cli"],"backgroundTag":"missing-required-config-field","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"}