nautechsystems/nautilus_trader · error

Invalid `exec_algorithm_id`/`actor_id` type

Error message

Invalid `exec_algorithm_id`/`actor_id` type

What it means

In the Python bindings' exec_algorithm_id setter, the bound id object is tried as ExecAlgorithmId, ActorId, then plain string; if none extract successfully the setter bails. The Python object passed is not a recognized identifier type.

Source

Thrown at crates/trading/src/python/algorithm.rs:1273

    ///
    /// # Errors
    ///
    /// Returns an error if an ID has an unsupported type or invalid value.
    pub fn configure_from_py_config(&mut self, config: &Bound<'_, PyAny>) -> anyhow::Result<bool> {
        let id = config
            .getattr("exec_algorithm_id")
            .ok()
            .filter(|id| !id.is_none())
            .or_else(|| config.getattr("actor_id").ok().filter(|id| !id.is_none()));
        let has_id = if let Some(id) = id {
            let exec_algorithm_id = if let Ok(exec_algorithm_id) = id.extract::<ExecAlgorithmId>() {
                exec_algorithm_id
            } else if let Ok(actor_id) = id.extract::<ActorId>() {
                ExecAlgorithmId::new_checked(actor_id.inner())?
            } else if let Ok(id) = id.extract::<String>() {
                ExecAlgorithmId::new_checked(&id)?
            } else {
                anyhow::bail!("Invalid `exec_algorithm_id`/`actor_id` type");
            };
            self.set_exec_algorithm_id(exec_algorithm_id);
            true
        } else {
            false
        };

        if let Ok(log_events) = config.getattr("log_events")
            && let Ok(log_events) = log_events.extract::<bool>()
        {
            self.set_log_events(log_events);
        }

        if let Ok(log_commands) = config.getattr("log_commands")
            && let Ok(log_commands) = log_commands.extract::<bool>()
        {
            self.set_log_commands(log_commands);
        }

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Pass an ExecAlgorithmId or ActorId instance, or the algorithm id as a str
  2. Coerce the value: ExecAlgorithmId(value) before assignment (or str(value) if it is an ID string)
  3. Validate the config value's type before constructing the config object

Example fix

# before
config.exec_algorithm_id = 12345
# after
config.exec_algorithm_id = ExecAlgorithmId("EMA-CROSS", "EXEC-001")  # or a valid string id
Defensive patterns

Strategy: type-guard

Validate before calling

assert isinstance(cfg["exec_algorithm_id"], (ExecAlgorithmId, ActorId, str)), f"bad exec_algorithm_id type: {type(cfg['exec_algorithm_id'])}"

Type guard

def is_valid_exec_algorithm_id(v) -> bool: return isinstance(v, (ExecAlgorithmId, ActorId, str))

Try / catch

try:
    config.exec_algorithm_id = value
except Exception:
    config.exec_algorithm_id = ExecAlgorithmId(str(value))

Prevention

When it happens

Trigger: Assigning a config/exec_algorithm_id attribute a value that is not an ExecAlgorithmId, ActorId, or str — e.g. a None, an int, or an arbitrary Python object.

Common situations: Passing None or an int where a string/identifier is expected in a Python config dict; building configs programmatically with unvalidated values; type confusion after refactoring the config schema.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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