AprilNEA/OpenLogi · error
sanitized Bolt receiver identity is not ASCII
Error message
sanitized Bolt receiver identity is not ASCII
What it means
`derive_replay_route` rebuilds a `DeviceRoute::Bolt` for replay from the cassette's audit record of sanitized identities. The sanitized receiver unique-id replacement must be exactly 16 bytes of ASCII (it becomes the receiver UID string); if it isn't, replay cannot reconstruct a valid route and this error is thrown (distinct sibling messages cover the non-16-byte vs non-ASCII cases).
Solutions
- Re-record the fixture so the sanitizer produces a correct 16-byte ASCII receiver unique-id
- Fix the audit `replacements` entry to hold a 16-byte ASCII synthetic value (and keep it consistent with every place it appears)
- Check cassette/schema version compatibility between the producing and replaying tool versions
- Validate the cassette with the fixture crate's privacy/relationship verification before replay
Example fix
// before (hand-edited audit) [[replacements]] kind = "receiver-unique-id" synthetic_value = "abc" // after [[replacements]] kind = "receiver-unique-id" synthetic_value = "A1B2C3D4E5F60718" # 16 ASCII bytes
Defensive patterns
Strategy: validation
Validate before calling
fn replay_route_supported(audit: &CassetteAudit) -> bool {
audit.replacements.iter()
.filter(|r| r.kind == SanitizedIdentityKind::ReceiverUniqueId)
.all(|r| r.synthetic_value.len() == 16 && r.synthetic_value.is_ascii())
} Type guard
fn is_valid_receiver_uid(value: &[u8]) -> bool {
value.len() == 16 && value.is_ascii()
} Try / catch
match derive_replay_route(audit, route) {
Ok(r) => replay(r),
Err(e) if e.to_string().contains("sanitized Bolt receiver identity") =>
eprintln!("cassette audit identity is malformed; re-record the fixture"),
Err(e) => return Err(e.into()),
} Prevention
- Never hand-edit audit `synthetic_value` entries; regenerate them via the sanitizer
- Pin cassette schema versions between producer and consumer tools
- Run the fixture crate's privacy/relationship verification before replay
- Re-record fixtures rather than porting audits across sanitizer versions
When it happens
Trigger: Replaying or validating a cassette whose audit lists a `ReceiverUniqueId` sanitized replacement that is not 16-byte ASCII — e.g. a cassette produced by an older sanitizer, hand-edited audit, or corrupted synthetic value.
Common situations: Replaying cassettes generated before the sanitizer enforced the 16-byte ASCII format, fixtures edited by hand for privacy review, or an audit file truncated/corrupted in transit.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- cassette audit has no sanitized receiver identity
- read-only HID++ case capture unexpectedly opened a raw…
- no sanitized channel candidate reproduced the captured…
- sanitized channel candidates reproduced the capture; target…
- sanitized Bolt receiver identity is not 16-byte ASCII
AI-assisted analysis of AprilNEA/OpenLogi@e846e6f4b4 (2026-09-13).
Data as JSON: /api/errors/56e44c0dcee17fcc.
Report an issue: GitHub.
Appendix: source
Thrown at crates/openlogi-cli/src/cmd/fixture/record_case/replay.rs:120
id: cassette.channel.clone(),
connection: ChannelConnection::Connected,
report_support: cassette.report_support,
}],
}
}
fn derive_replay_route(
selected_route: &DeviceRoute,
audit: &HidCassetteAudit,
) -> Result<DeviceRoute> {
match selected_route {
DeviceRoute::Bolt { slot, .. } => {
let value = unique_replacement(audit, SanitizedIdentityKind::ReceiverUniqueId)?;
if value.len() != 16 || !value.is_ascii() {
bail!("sanitized Bolt receiver identity is not 16-byte ASCII");
}
let receiver_uid = std::str::from_utf8(value)
.map_err(|_| anyhow::anyhow!("sanitized Bolt receiver identity is not ASCII"))?
.to_string();
Ok(DeviceRoute::Bolt {
receiver_uid,
slot: *slot,
})
}
DeviceRoute::Unifying { slot, .. } => {
let value = unique_replacement(audit, SanitizedIdentityKind::ReceiverSerialNumber)?;
if value.len() != 4 {
bail!("sanitized Unifying receiver identity is not four bytes");
}
Ok(DeviceRoute::Unifying {
receiver_uid: uppercase_hex(value),
slot: *slot,
})
}
DeviceRoute::Direct {
vendor_id,View on GitHub (pinned to e846e6f4b4)