EpicGames/lore · error
hex encode failed
Error message
hex encode failed
What it means
to_hex_str encodes src into the caller-provided dst buffer with hex::encode_to_slice and panics via .expect if the encoding fails. The function's contract (debug_assert dst.len() == src.len()*2) means this should be impossible; the panic is a deliberate fail-fast instead of silently returning wrong data. It fires only when the output buffer is too small for the hex representation.
Solutions
- Size dst as exactly src.len()*2 bytes before calling
- If the input length changed (e.g. digest size), update every buffer sizing constant together
- Use a fixed-size helper or const-generic buffer to keep src and dst lengths in sync
- Optionally replace with hex::encode_into reusing an owned String to eliminate buffer sizing entirely
Example fix
// before let mut buf = [0u8; 32]; // sized for 16-byte src let s = to_hex_str(&digest, &mut buf); // digest is 32 bytes -> panic // after let mut buf = [0u8; 64]; // digest.len() * 2 let s = to_hex_str(&digest, &mut buf);
Defensive patterns
Strategy: validation
Validate before calling
fn hex_buffer_ok(src: &[u8], dst: &[u8]) -> bool { dst.len() == src.len() * 2 } Type guard
fn sized_hex_buf<const N: usize>(src: &[u8]) -> Option<[u8; N]> {
(N == src.len() * 2).then(|| [0u8; N])
} Prevention
- Always allocate hex buffers as src.len()*2 or with fixed-size arrays tied to the digest constant
- Use const generics or newtypes encoding the digest length to keep sizes in sync
- Prefer hex::encode returning an owned String when buffer reuse is not required
- Add a unit test for every digest length constant change
When it happens
Trigger: Calling to_hex_str with a dst slice shorter than src.len()*2 (in release builds, where the debug_assert is compiled out, encode_to_slice returns Err(FromHexError::InvalidStringLength) and the expect panics).
Common situations: A caller sized the buffer from a wrong constant (e.g. hash length changed from 16 to 32 bytes after a version change), reused a buffer sized for a different identifier, or computed dst length as src.len() instead of src.len()*2.
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
- Failed to open log file
- {e}
- Networking not supported on this OS
- could not get available parallelism
- hex was not valid utf8
AI-assisted analysis of EpicGames/lore@074eb0b0d1 (2026-09-13).
Data as JSON: /api/errors/32b70758466a355a.
Report an issue: GitHub.
Appendix: source
Thrown at lore-revision/src/util.rs:23
pub mod config;
pub mod encoding;
pub mod fs;
pub mod inflight;
pub mod path;
pub mod serde;
pub mod task_queue;
pub mod time;
pub mod url;
/// Provides a mechanism for converting data to a hex `&str` without unnecessary allocations.
/// Note: the `dst` parameter must be passed in in order to give us something to which we can tie
/// the lifetime of the returned &str.
#[inline]
pub fn to_hex_str<'a>(src: &[u8], dst: &'a mut [u8]) -> &'a str {
debug_assert_eq!(dst.len(), src.len() * 2);
// These should never fail, but if it does, we'd rather panic than use a default value
hex::encode_to_slice(src, dst).expect("hex encode failed");
std::str::from_utf8(dst).expect("hex was not valid utf8")
}
View on GitHub (pinned to 074eb0b0d1)