nautechsystems/nautilus_trader · error

Strategy order_id_tag conflict for '{order_id_tag}', explici

Error message

Strategy order_id_tag conflict for '{order_id_tag}', explicitly define unique order_id_tag values

What it means

ensure_unique_order_id_tag checks a candidate strategy order_id_tag against tags already used by registered actors/strategies in the trader. Order ID tags must be unique per trader so generated order IDs don't collide; a duplicate tag is rejected with this error.

Source

Thrown at crates/system/src/registration.rs:60

                    .unwrap_or_else(|| type_name::<T>());
                strategy_type.to_string()
            },
            |strategy_id| strategy_id.to_string(),
        )
}

pub(crate) fn base_strategy_id(strategy_id: &str) -> String {
    strategy_id
        .rsplit_once('-')
        .map_or_else(|| strategy_id.to_string(), |(base, _)| base.to_string())
}

pub(crate) fn ensure_unique_order_id_tag(
    existing_order_id_tags: &[&str],
    order_id_tag: &str,
) -> anyhow::Result<()> {
    if existing_order_id_tags.contains(&order_id_tag) {
        anyhow::bail!(
            "Strategy order_id_tag conflict for '{order_id_tag}', explicitly define unique order_id_tag values",
        );
    }

    Ok(())
}

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Assign a unique explicit order_id_tag to each strategy config (e.g. "001", "002").
  2. If using defaults, instantiate each strategy with a distinct tag before registration.
  3. Review registered strategies to see which tag is taken and choose a free one.

Example fix

// before
config_a = MyStrategyConfig(order_id_tag="001")
config_b = MyStrategyConfig(order_id_tag="001")  # conflict
// after
config_b = MyStrategyConfig(order_id_tag="002")
Defensive patterns

Strategy: validation

Validate before calling

used = {s.config.order_id_tag for s in trader.strategies()}
assert config.order_id_tag not in used, \
    f"order_id_tag '{config.order_id_tag}' already in use: {sorted(used)}"

Type guard

def tag_is_free(order_id_tag: str, existing_tags) -> bool:
    return order_id_tag not in existing_tags

Try / catch

try:
    trader.add_strategy(strategy)
except Exception as e:
    if "order_id_tag conflict" in str(e):
        logger.error("Duplicate order_id_tag: %s", e)
        raise ValueError("Assign a unique order_id_tag per strategy") from e
    raise

Prevention

When it happens

Trigger: Adding a second strategy (via prepare_python_strategy_instance, add_strategy_id_with_subscriptions, or prepare_strategy_for_registration) whose config carries an order_id_tag already claimed by another strategy, or two strategies both relying on a colliding default tag.

Common situations: Copy-pasting strategy configs without changing order_id_tag, running multiple instances of the same strategy class with default tags, template configs deployed twice under different strategy ids.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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