nautechsystems/nautilus_trader · error

invalid Bybit smp_type: '{s}', expected None, CancelMaker, C

Error message

invalid Bybit smp_type: '{s}', expected None, CancelMaker, CancelTaker or CancelBoth

What it means

parse_smp_type parses a user-supplied self-match-prevention (smp_type) string into the BybitOrderSmpType enum. Matching is case-insensitive over the fixed set none/cancelmaker/canceltaker/cancelboth; any other string raises this anyhow error. It is reached via order submission (py_submit_order, py_new), TP/SL params, or config deserialization.

Source

Thrown at crates/adapters/bybit/src/common/parse.rs:1740

    } else if let Some(n) = value.as_i64() {
        Some(n.to_string())
    } else {
        value.as_u64().map(|n| n.to_string())
    }
}

/// Parses a Bybit self-match prevention type from an order parameter or configuration value.
///
/// # Errors
///
/// Returns an error for any value outside the four types Bybit accepts on an order.
pub fn parse_smp_type(s: &str) -> anyhow::Result<BybitOrderSmpType> {
    match s.to_ascii_lowercase().as_str() {
        "none" => Ok(BybitOrderSmpType::None),
        "cancelmaker" => Ok(BybitOrderSmpType::CancelMaker),
        "canceltaker" => Ok(BybitOrderSmpType::CancelTaker),
        "cancelboth" => Ok(BybitOrderSmpType::CancelBoth),
        _ => anyhow::bail!(
            "invalid Bybit smp_type: '{s}', expected None, CancelMaker, CancelTaker or CancelBoth"
        ),
    }
}

/// Deserializes an optional self-match prevention type for a client configuration.
///
/// Routes the configured text through [`parse_smp_type`] so a serialized config reports an unknown
/// value instead of carrying it silently.
///
/// # Errors
///
/// Returns an error for any value outside the four types Bybit accepts on an order.
pub fn deserialize_optional_smp_type<'de, D: serde::Deserializer<'de>>(
    d: D,
) -> Result<Option<BybitOrderSmpType>, D::Error> {
    let Some(value) = Option::<String>::deserialize(d)? else {
        return Ok(None);

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Use exactly one of: none, cancelmaker, canceltaker, cancelboth (case does not matter)
  2. Check the config/order params for stray prefixes, underscores or hyphens and remove them
  3. If SMP is not needed, set smp_type to none or omit it

Example fix

// before
params.insert("smp_type", "CANCEL_MAKER");
// after
params.insert("smp_type", "CancelMaker");
Defensive patterns

Strategy: validation

Validate before calling

VALID_SMP_TYPES = {"none", "cancelmaker", "canceltaker", "cancelboth"}
assert smp_type.lower() in VALID_SMP_TYPES, f"invalid smp_type: {smp_type}"

Type guard

fn is_valid_smp_type(s: &str) -> bool {
    matches!(s.to_ascii_lowercase().as_str(), "none" | "cancelmaker" | "canceltaker" | "cancelboth")
}

Try / catch

match parse_smp_type(s) {
    Ok(t) => use(t),
    Err(e) => { log::error!("{e}"); BybitOrderSmpType::None }
}

Prevention

When it happens

Trigger: Passing smp_type as an order/TP-SL param or in client config with a misspelled or unsupported value, e.g. 'CANCEL_MAKER', 'cancel-maker', 'smptype_cancelboth', or an empty string.

Common situations: Config mistakes copying values from another exchange adapter's naming convention (snake_case or prefixed), typos, or leaving a placeholder value in the config file.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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