nautechsystems/nautilus_trader · error · anyhow::Error
missing raw broker client order ID payload
Error message
missing raw broker client order ID payload
What it means
Decoding a broker-prefixed client order ID whose signal byte marks a raw (unpacked) payload: everything after the signal byte should be the verbatim ClientOrderId, but the payload is empty, leaving nothing to reconstruct.
Source
Thrown at crates/adapters/binance/src/common/encoder.rs:257
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
),
}
}
fn build_encoded(prefix: &str, signal: u8, b62: &[u8]) -> String {
let mut result = String::with_capacity(prefix.len() + 1 + b62.len());
result.push_str(prefix);
result.push(signal as char);
// base62 output is always valid ASCII
result.push_str(std::str::from_utf8(b62).expect("base62 is valid UTF-8"));View on GitHub (pinned to a4b06ed870)
Solutions
- Use a longer, distinctive BinanceBrokerId
- Regenerate the order IDs with the current adapter encoder rather than reconstructing them by hand
- Validate stored/captured IDs for length before decoding
Example fix
# before broker_id = "B" # prefix+signal collisions trivial # after broker_id = "NAUTILUS7F" # distinctive, collisions virtually impossible
Defensive patterns
Strategy: validation
Validate before calling
fn raw_payload_present(id: &str, prefix: &str) -> bool {
id.strip_prefix(prefix).is_none_or(|p| p.len() >= 2) // signal + payload
} Type guard
fn broker_id_decodable(id: &str, prefix: &str) -> bool {
id.strip_prefix(prefix).is_none_or(|p| !p.is_empty() && p.len() > 1)
} Try / catch
let decoded = decode_broker_id_checked(encoded, broker_id)
.unwrap_or_else(|e| {
log::warn!("raw payload missing for '{encoded}': {e}");
encoded.to_string()
}); Prevention
- Choose broker_id values unlikely to appear in any external ID
- Validate stored IDs (length > prefix + 1) before batch-decoding
- Monitor for decode failures as an early signal of ID collisions
When it happens
Trigger: A clientOrderId consisting exactly of broker prefix + raw-signal character with no following bytes - typically a truncated ID or a foreign ID that collides with a short broker prefix.
Common situations: Short/generic broker_id values colliding with exchange-generated IDs; IDs cut down to the length limit; malformed test fixtures.
Related errors
- missing broker client order ID signal
- invalid O-format broker client order ID payload length
- invalid UUID broker client order ID payload length
- 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/300c34855275732d.
Report an issue: GitHub.