nautechsystems/nautilus_trader · error

missing broker client order ID signal

Error message

missing broker client order ID signal

What it means

Binance order IDs are round-tripped through a compact encoding: an optional broker prefix followed by a one-byte 'signal' byte identifying the payload format (hyphenated UUID, non-hyphenated, etc.). decode_broker_id_checked found the prefix but then hit an empty payload — no signal byte at all — so it cannot determine the format and bails.

Solutions

  1. Check the original order ID for truncation — Binance caps newClientOrderId length; ensure encoded IDs fit within the limit before submitting.
  2. Regenerate the order ID with the encoder and resubmit; do not attempt to decode the corrupted value.
  3. Guard decode calls with a length check (payload after prefix must be >= 1 byte) to give a clearer failure upstream.
  4. Verify the ID was produced by this adapter's encoder and not mixed with IDs from another integration.

Example fix

// before
let Some((&signal, data)) = payload.as_bytes().split_first() else {
    anyhow::bail!("missing broker client order ID signal");
};
// after: validate length at encode time so this cannot occur
anyhow::ensure!(
    encoded.len() <= MAX_BINANCE_CLIENT_ORDER_ID_LEN,
    "encoded client order ID exceeds Binance limit: {}",
    encoded.len()
);
Defensive patterns

Strategy: validation

Validate before calling

fn is_decodable_broker_id(id: &str, prefix: &str) -> bool {
    id.strip_prefix(prefix).map_or(false, |p| !p.is_empty())
}

Try / catch

match decode_client_order_id(&encoded) {
    Ok(id) => id,
    Err(e) if e.to_string().contains("missing broker client order ID signal") => {
        eprintln!("order ID truncated: {encoded}");
        encoded.to_string()
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling decode_broker_id or decode_client_order_id on a string that consists of exactly the broker prefix (e.g. "x-NAU-") with nothing after it — typically a truncated or corrupted order ID, often after the exchange truncated a long newClientOrderId on the wire.

Common situations: Binance truncating client order IDs that exceed its length limit, cutting off the encoded payload; hand-editing or logging/marshalling bugs that clip the ID string; using an ID produced by a different encoder version.

Understand the failure class

Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.

Related errors


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

Appendix: source

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

/// Returns an error if the broker-prefixed encoding is malformed or the
/// decoded client order ID is invalid.
pub(crate) fn decode_client_order_id(
    encoded: &str,
    broker_id: &str,
) -> 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))

View on GitHub (pinned to 18893faf8b)