nautechsystems/nautilus_trader · error · anyhow::Error
invalid UUID broker client order ID payload length
Error message
invalid UUID broker client order ID payload length
What it means
Decoding a broker-prefixed client order ID whose signal byte marks the UUID-format payload: the base62 characters after the signal must be exactly UUID_B62_LEN long. A different length means the value cannot be decoded back into the original UUID-based ClientOrderId.
Source
Thrown at crates/adapters/binance/src/common/encoder.rs:248
let Some(payload) = encoded.strip_prefix(&prefix) else {
return Ok(encoded.to_string());
};
let Some((&signal, data)) = payload.as_bytes().split_first() else {
anyhow::bail!("missing broker client order ID signal");
};
match signal {
SIGNAL_O_HYPHENS | SIGNAL_O_NO_HYPHENS => {
anyhow::ensure!(
data.len() == O_FORMAT_B62_LEN,
"invalid O-format broker client order ID payload length"
);
let packed = decode_base62(data).context("invalid O-format broker client order ID")?;
Ok(unpack_o_format(packed, signal == SIGNAL_O_HYPHENS))
}
SIGNAL_UUID_HYPHENS | SIGNAL_UUID_NO_HYPHENS => {
anyhow::ensure!(
data.len() == UUID_B62_LEN,
"invalid UUID broker client order ID payload length"
);
let value = decode_base62(data).context("invalid UUID broker client order ID")?;
Ok(format_uuid(value, signal == SIGNAL_UUID_HYPHENS))
}
SIGNAL_RAW => {
let raw = std::str::from_utf8(data).context("invalid raw broker client order ID")?;
anyhow::ensure!(
!raw.is_empty(),
"missing raw broker client order ID payload"
);
Ok(raw.to_string())
}
_ => anyhow::bail!(
"unknown broker client order ID signal byte '{}'",
signal as char
),View on GitHub (pinned to a4b06ed870)
Solutions
- Align encoder and decoder versions - orders written by an older adapter must be read by that version or treated as opaque
- Choose a distinctive broker_id to avoid collisions with exchange- or user-generated IDs
- Treat un-decodable IDs as raw values instead of failing the whole order update path
Example fix
// before
let cid = decode_broker_id_checked(encoded, broker_id)?;
// after: fall back to treating the value as an opaque ID
let cid = decode_broker_id_checked(encoded, broker_id)
.map(ClientOrderId::new)
.unwrap_or_else(|_| ClientOrderId::new(encoded.to_string())); Defensive patterns
Strategy: type-guard
Validate before calling
fn is_valid_uuid_format(id: &str, prefix: &str, uuid_len: usize) -> bool {
match id.strip_prefix(prefix) {
Some(p) if !p.is_empty() => p[1..].len() == uuid_len,
_ => true,
}
} Type guard
fn looks_like_adapter_uuid_id(id: &str, prefix: &str, uuid_b62_len: usize) -> bool {
id.strip_prefix(prefix).is_some_and(|p| p.len() == 1 + uuid_b62_len)
} Try / catch
match decode_broker_id_checked(encoded, broker_id) {
Ok(decoded) => ClientOrderId::new_checked(decoded)?,
Err(e) => {
log::warn!("UUID-format decode failed for '{encoded}': {e}");
ClientOrderId::new(encoded) // opaque fallback
}
} Prevention
- Never mix adapter versions across the encode/decode lifecycle of the same orders
- Use distinctive broker prefixes to rule out foreign-ID collisions
- Log both the encoded and decoded forms when persisting so mismatches are diagnosable
When it happens
Trigger: A clientOrderId starting with broker prefix + UUID signal byte but whose payload length is not the fixed UUID base62 length - truncated IDs, foreign IDs colliding with the prefix, or an encoder/decoder version mismatch.
Common situations: Upgrading adapter versions that changed UUID packing; replaying orders created by an older build; user-defined IDs that begin with the configured prefix followed by a UUID signal character.
Related errors
- missing broker client order ID signal
- invalid O-format broker client order ID payload length
- missing raw broker client order ID payload
- unknown broker client order ID signal byte '{}'
- {standard_key_var} not found in config or environment
AI-assisted analysis of nautechsystems/nautilus_trader@a4b06ed870 (2026-08-16).
Data as JSON: /api/errors/0d89f6411c1bb4d9.
Report an issue: GitHub.