nautechsystems/nautilus_trader · error · anyhow::Error

invalid O-format broker client order ID payload length

Error message

invalid O-format broker client order ID payload length

What it means

decode_broker_id_checked splits the broker client order ID payload into a one-byte signal and body. When the signal indicates the O-format (base62-packed, with or without hyphens), the remaining bytes must be exactly O_FORMAT_B62_LEN characters. This error means the payload length did not match that fixed size, so the payload is corrupt or was not produced by the matching encoder.

Solutions

  1. Re-encode the order ID with encode_o_format / the matching encoder from this crate instead of hand-building the payload.
  2. Verify the payload is a complete broker ID emitted by this adapter version; regenerate it rather than trimming/padding.
  3. Check that the full payload (signal byte + O_FORMAT_B62_LEN chars) was stored and passed — no truncation in the database or message queue.
  4. If the ID came from the exchange, confirm the original client order ID format actually matched the adapter's O-format before encoding.

Example fix

// before
let decoded = decode_client_order_id(truncated_payload)?;

// after
assert_eq!(truncated_payload.len(), 1 + O_FORMAT_B62_LEN);
let decoded = decode_client_order_id(truncated_payload)?;
Defensive patterns

Strategy: validation

Validate before calling

const O_FORMAT_B62_LEN: usize = /* per crate */ 22;
fn is_valid_o_payload(p: &[u8]) -> bool {
    p.len() == 1 + O_FORMAT_B62_LEN
        && matches!(p[0], SIGNAL_O_HYPHENS | SIGNAL_O_NO_HYPHENS)
}

Prevention

When it happens

Trigger: Calling decode_broker_id or decode_client_order_id with a payload whose first byte is SIGNAL_O_HYPHENS or SIGNAL_O_NO_HYPHENS but whose remainder is longer or shorter than O_FORMAT_B62_LEN — e.g. a truncated or hand-modified broker order ID, an ID produced by a different adapter version, or an unencoded Binance client order ID passed to the decoder.

Common situations: Migrating between adapter versions where the O-format encoding length changed; manually constructing or copy-pasting broker IDs; exchange-side truncation of long client order IDs when relayed back on order reports.

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


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/d986611c1464fd9e. Report an issue: GitHub.

Appendix: source

Thrown at crates/adapters/binance/src/common/encoder.rs:240

) -> anyhow::Result<ClientOrderId> {
    let decoded = decode_broker_id_checked(encoded, broker_id)?;
    ClientOrderId::new_checked(decoded)
        .with_context(|| format!("invalid Binance client order ID '{encoded}'"))
}

fn decode_broker_id_checked(encoded: &str, broker_id: &str) -> anyhow::Result<String> {
    let prefix = broker_prefix(broker_id);
    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(),

View on GitHub (pinned to 18893faf8b)