nautechsystems/nautilus_trader · error · anyhow::Error

Invalid IBOrderTags field {field}: {value}

Error message

Invalid IBOrderTags field {field}: {value}

What it means

Each key in the IBOrderTags JSON object must correspond to a known IBOrder field that normalize_order_tag_update recognizes. An unrecognized or malformed field name/value combination cannot be normalized, so the overlay aborts with the offending field and value in the message.

Source

Thrown at crates/adapters/interactive_brokers/src/execution/transform/tags.rs:84

    tags_map: &Map<String, Value>,
) -> anyhow::Result<()> {
    let mut order_value = serde_json::to_value(&*ib_order)
        .context("Failed to serialize IB order before applying IBOrderTags")?;

    for (key, value) in tags_map {
        let field = canonical_order_tag_key(key);
        if should_skip_generic_overlay(&field) {
            continue;
        }

        if field == "non_guaranteed" {
            apply_non_guaranteed_combo_tag(ib_order, value)?;
            sync_order_field(&mut order_value, "smart_combo_routing_params", ib_order)?;
            continue;
        }

        let Some(mut updates) = normalize_order_tag_update(&field, value) else {
            anyhow::bail!("Invalid IBOrderTags field {field}: {value}");
        };

        for (field, value) in updates.drain(..) {
            apply_order_field_update(ib_order, &mut order_value, &field, value)?;
        }
    }

    Ok(())
}

fn apply_order_field_update(
    ib_order: &mut IBOrder,
    order_value: &mut Value,
    field: &str,
    value: Value,
) -> anyhow::Result<()> {
    let Some(order_obj) = order_value.as_object_mut() else {
        anyhow::bail!("Failed to apply IBOrderTags because IB order JSON is not an object");

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Use only field names that exist on the IBOrder struct (check the struct's serde field names in the crate)
  2. Fix the value type to match the field (numbers unquoted, booleans as true/false, enums as valid IB strings) For combos, use the dedicated NonGuaranteed / smart_combo_routing_params keys instead of raw field names

Example fix

// before
{"OutsideRth": "yes"}
// after
{"outside_rth": true}
Defensive patterns

Strategy: validation

Validate before calling

for field in tags_obj.as_object().unwrap().keys() {
    assert!(KNOWN_IB_ORDER_FIELDS.contains(&field.as_str()), "unknown tag field: {field}");
}

Try / catch

match apply_ib_order_tags(&mut ib_order, &tags) {
    Err(e) if e.to_string().contains("Invalid IBOrderTags field") => {
        tracing::warn!("dropping malformed order tags: {e}");
    }
    other => other?,
}

Prevention

When it happens

Trigger: apply_ib_order_tag_json -> apply_ib_order_tag_overlay encountering a key not in the IBOrder schema (typo like 'timeinforce' variants it doesn't normalize, or fields like 'client_id') or a value of the wrong JSON type for a known field (e.g. string where number is expected).

Common situations: Typos in tag names ('outsidrth'), casing the adapter doesn't recognize, copy-pasting field names from IB's Java API that differ from this crate's serde field names, or passing numeric fields as strings.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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