{"record":{"id":"ed41a115e3f89bd9","repo":"AprilNEA/OpenLogi","slug":"a-sanitized-profile-route-is-not-addressable","errorCode":null,"errorMessage":"a sanitized profile route is not addressable","messagePattern":"a sanitized profile route is not addressable","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/openlogi-cli/src/cmd/fixture/record_profile.rs","lineNumber":251,"sourceCode":"        .iter()\n        .map(|device| {\n            DeviceRoute::device_route_for(&retained, device.slot).ok_or_else(|| {\n                anyhow!(\"a retained Agent inventory route is not safely addressable\")\n            })\n        })\n        .collect::<Result<Vec<_>>>()?;\n    let retained_selected = if retained.receiver.unique_id.is_none() {\n        0\n    } else {\n        selected_device\n    };\n    sanitize::inventory(&mut retained)?;\n    let profile_routes = retained\n        .paired\n        .iter()\n        .map(|device| {\n            DeviceRoute::device_route_for(&retained, device.slot)\n                .ok_or_else(|| anyhow!(\"a sanitized profile route is not addressable\"))\n        })\n        .collect::<Result<Vec<_>>>()?;\n    let selected_route = profile_routes\n        .get(retained_selected)\n        .cloned()\n        .ok_or_else(|| anyhow!(\"the sanitized selected profile route is absent\"))?;\n\n    let mut settings = Vec::with_capacity(retained.paired.len());\n    for ((source_route, profile_route), device) in source_routes\n        .iter()\n        .zip(profile_routes)\n        .zip(&retained.paired)\n    {\n        settings.push(capture_hidpp_settings(client, source_route, profile_route, device).await?);\n    }\n    Ok((vec![retained], Vec::new(), settings, selected_route))\n}\n","sourceCodeStart":233,"sourceCodeEnd":269,"githubUrl":"https://github.com/AprilNEA/OpenLogi/blob/e846e6f4b4405e33bd6a9aaf949a482ce34cb6d8/crates/openlogi-cli/src/cmd/fixture/record_profile.rs#L233-L269","documentation":"Raised in `capture_inventory` after `sanitize::inventory` rewrites the retained inventory: `DeviceRoute::device_route_for` returns `None` for a device in the sanitized profile. Sanitization replaces real identities with synthetic ones; if it leaves slot/pairing data inconsistent, route construction fails. This is a sanitizer invariant: sanitization must preserve addressability.","triggerScenarios":"`capture_inventory` calls `sanitize::inventory(&mut retained)` and then rebuilds routes; a sanitizer change (or bug) drops or corrupts slot/receiver metadata so `device_route_for` can no longer resolve a device.","commonSituations":"Recently modified sanitize rules in `record_profile/sanitize.rs` that renumber or prune paired devices without updating slots; a synthetic-identity policy change breaking route invariants.","solutions":["Run the sanitize module's tests (`cargo test -p openlogi-cli sanitize` or the fixture tests) to find which sanitizer rule breaks route addressability.","Ensure `sanitize::inventory` preserves each retained device's slot or updates routes consistently after pruning.","As a user, update the CLI to a version where the sanitizer is fixed; this is a code bug, not a configuration issue."],"exampleFix":"// before: prune paired devices without re-slotting\nretained.paired.retain(|d| wanted);\n// after: keep slots consistent with retained receiver metadata\nretained.paired.retain(|d| wanted);\n// (and ensure device_route_for still resolves each retained device.slot)","handlingStrategy":"validation","validationCode":"// after sanitize, assert routes still resolve\nsanitize::inventory(&mut retained)?;\nfor d in &retained.paired {\n    assert!(DeviceRoute::device_route_for(&retained, d.slot).is_some());\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Extend the sanitize test suite to assert post-sanitize route addressability.","Keep sanitizer pruning and slot updates in the same operation.","Run `cargo test -p openlogi-cli` after any sanitize.rs change."],"tags":["rust","cli","sanitization","device-route"],"backgroundTag":"internal-invariant-violation","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"}