nautechsystems/nautilus_trader · error

Failed to parse `ct_val` '{}' for {}: {e}

Error message

Failed to parse `ct_val` '{}' for {}: {e}

What it means

parse_multiplier_product parses ct_val (contract value per unit) into a Decimal. A non-empty ct_val that cannot be parsed as a decimal raises this error naming the value and inst_id. Empty ct_val defaults to Decimal::ONE.

Source

Thrown at crates/adapters/okx/src/common/parse.rs:1915

    }

    let mult_value = if definition.ct_mult.is_empty() {
        Decimal::ONE
    } else {
        Decimal::from_str(&definition.ct_mult).map_err(|e| {
            anyhow::anyhow!(
                "Failed to parse `ct_mult` '{}' for {}: {e}",
                definition.ct_mult,
                definition.inst_id
            )
        })?
    };

    let val_value = if definition.ct_val.is_empty() {
        Decimal::ONE
    } else {
        Decimal::from_str(&definition.ct_val).map_err(|e| {
            anyhow::anyhow!(
                "Failed to parse `ct_val` '{}' for {}: {e}",
                definition.ct_val,
                definition.inst_id
            )
        })?
    };

    let product = mult_value * val_value;
    Ok(Some(Quantity::from(product.to_string())))
}

/// Trait for instrument-specific parsing logic.
trait InstrumentParser {
    /// Parses instrument-specific fields and creates the final instrument.
    fn parse_specific_fields(
        &self,
        definition: &OKXInstrument,
        common: CommonInstrumentData,

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Verify ct_val in the failing payload is a plain decimal string (or empty to default to 1)
  2. Re-fetch the instrument definition from OKX /public/instruments
  3. Normalize the string (trim, strip currency suffixes) before parsing
  4. Leave ct_val empty when the contract multiplier should default to 1
Defensive patterns

Strategy: validation

Validate before calling

fn ct_val_valid(def: &OKXInstrument) -> bool {
    def.ct_val.is_empty() || def.ct_val.parse::<rust_decimal::Decimal>().is_ok()
}

Try / catch

let multiplier = match parse_multiplier_product(&definition) {
    Ok(m) => m,
    Err(e) => { tracing::error!("ct_val parse failed for {}: {e:#}", definition.inst_id); return; }
};

Prevention

When it happens

Trigger: Calling parse_swap_instrument / parse_futures_instrument / parse_option_instrument / parse_specific_fields with an instrument definition where ct_val contains a non-decimal string (e.g. scientific notation the Decimal parser rejects, currency-annotated values, or empty-vs-garbage confusion).

Common situations: Malformed cached instrument metadata; OKX adding fields or changing formats for newer contract types; fixtures hand-written with wrong ct_val values.

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/1a01c82b51254e8a. Report an issue: GitHub.