{"record":{"id":"c99dcbced62dc0f4","repo":"AprilNEA/OpenLogi","slug":"sanitized-bolt-receiver-identity-is-not-16-byte-ascii","errorCode":null,"errorMessage":"sanitized Bolt receiver identity is not 16-byte ASCII","messagePattern":"sanitized Bolt receiver identity is not 16-byte ASCII","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/openlogi-cli/src/cmd/fixture/record_case/replay.rs","lineNumber":117,"sourceCode":"            receiver_slots,\n        }],\n        channels: vec![ReplayChannel {\n            id: cassette.channel.clone(),\n            connection: ChannelConnection::Connected,\n            report_support: cassette.report_support,\n        }],\n    }\n}\n\nfn derive_replay_route(\n    selected_route: &DeviceRoute,\n    audit: &HidCassetteAudit,\n) -> Result<DeviceRoute> {\n    match selected_route {\n        DeviceRoute::Bolt { slot, .. } => {\n            let value = unique_replacement(audit, SanitizedIdentityKind::ReceiverUniqueId)?;\n            if value.len() != 16 || !value.is_ascii() {\n                bail!(\"sanitized Bolt receiver identity is not 16-byte ASCII\");\n            }\n            let receiver_uid = std::str::from_utf8(value)\n                .map_err(|_| anyhow::anyhow!(\"sanitized Bolt receiver identity is not ASCII\"))?\n                .to_string();\n            Ok(DeviceRoute::Bolt {\n                receiver_uid,\n                slot: *slot,\n            })\n        }\n        DeviceRoute::Unifying { slot, .. } => {\n            let value = unique_replacement(audit, SanitizedIdentityKind::ReceiverSerialNumber)?;\n            if value.len() != 4 {\n                bail!(\"sanitized Unifying receiver identity is not four bytes\");\n            }\n            Ok(DeviceRoute::Unifying {\n                receiver_uid: uppercase_hex(value),\n                slot: *slot,\n            })","sourceCodeStart":99,"sourceCodeEnd":135,"githubUrl":"https://github.com/AprilNEA/OpenLogi/blob/e846e6f4b4405e33bd6a9aaf949a482ce34cb6d8/crates/openlogi-cli/src/cmd/fixture/record_case/replay.rs#L99-L135","documentation":"`derive_replay_route` rebuilds the concrete device route from sanitized audit data. For a Bolt route it reads the sanitized ReceiverUniqueId replacement, which must be exactly 16 ASCII bytes to form a valid receiver UID; otherwise the sanitized fixture data is malformed and the error is thrown.","triggerScenarios":"Replaying a Bolt-routed fixture whose audit identity replacement for ReceiverUniqueId is missing, the wrong length (not 16 bytes), or contains non-ASCII bytes — e.g. a fixture produced by an older/buggy sanitizer or hand-edited audit JSON.","commonSituations":"Hand-editing sanitized fixture identities; a sanitizer change altering the replacement format; a corrupted fixture cache; using a fixture recorded against a different identity policy version.","solutions":["Re-record the fixture so the sanitizer regenerates a valid 16-byte ASCII receiver UID","Inspect the fixture's audit section and correct the ReceiverUniqueId replacement to exactly 16 ASCII bytes","Regenerate sanitized identities via the openlogi-fixture synthetic identity policy instead of editing them manually"],"exampleFix":"// before (hand-edited audit)\n\"receiver_unique_id\": \"ABC123\"            // 6 bytes\n// after\n\"receiver_unique_id\": \"A1B2C3D4E5F6A7B8\"   // 16 ASCII bytes","handlingStrategy":"validation","validationCode":"fn valid_bolt_uid(v: &[u8]) -> bool { v.len() == 16 && v.is_ascii() }\n// check before replaying a Bolt fixture\nassert!(valid_bolt_uid(&audit.receiver_unique_id), \"sanitized Bolt UID must be 16 ASCII bytes\");","typeGuard":"fn valid_bolt_uid(v: &[u8]) -> bool {\n    v.len() == 16 && v.is_ascii()\n}","tryCatchPattern":null,"preventionTips":["Never hand-edit sanitized identity fields in fixtures","Regenerate identities through the openlogi-fixture synthetic identity policy","Validate fixture audit JSON after sanitizer version changes"],"tags":["fixture","sanitization","bolt","identity","validation"],"backgroundTag":"invalid-identifier-format","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"}