nautechsystems/nautilus_trader · error · anyhow::Error

Invalid `actor_id` type

Error message

Invalid `actor_id` type

What it means

When configuring an actor from Python, the `actor_id` attribute must be either an ActorId instance or a string parseable into one. If the Python object extracts as neither, the builder bails with this message. The library throws it to fail fast on a mistyped identifier rather than silently assigning a default.

Source

Thrown at crates/common/src/python/actor.rs:2855

    config: Option<&Bound<'_, PyAny>>,
) -> anyhow::Result<ActorId> {
    let mut actor = actor_obj
        .extract::<PyRefMut<PyDataActor>>()
        .map_err(Into::<PyErr>::into)
        .map_err(|e| anyhow::anyhow!("Failed to extract PyDataActor: {e}"))?;

    if let Some(config) = config {
        if let Some(actor_id) = config
            .getattr("actor_id")
            .ok()
            .filter(|actor_id| !actor_id.is_none())
        {
            let actor_id = if let Ok(actor_id) = actor_id.extract::<ActorId>() {
                actor_id
            } else if let Ok(actor_id) = actor_id.extract::<String>() {
                ActorId::new_checked(&actor_id)?
            } else {
                anyhow::bail!("Invalid `actor_id` type");
            };
            actor.set_actor_id(actor_id);
        }

        if let Some(log_events) = extract_bool_config_attr(config, "log_events") {
            actor.set_log_events(log_events);
        }

        if let Some(log_commands) = extract_bool_config_attr(config, "log_commands") {
            actor.set_log_commands(log_commands);
        }
    }

    actor.set_python_instance(actor_obj)?;
    apply_class_derived_actor_id(&mut actor, actor_obj)?;
    Ok(actor.actor_id())
}

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Pass actor_id as a string, e.g. actor_id="MyActor-001", or as an ActorId instance.
  2. Omit actor_id entirely to let the system assign one automatically.
  3. Coerce non-string ids to str before building the config.

Example fix

// before
config = MyActorConfig(actor_id=42)
// after
config = MyActorConfig(actor_id="42")
Defensive patterns

Strategy: validation

Validate before calling

actor_id = config.get("actor_id")
if actor_id is not None and not isinstance(actor_id, (ActorId, str)):
    raise TypeError(f"actor_id must be ActorId or str, got {type(actor_id).__name__}")

Type guard

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

Try / catch

try:
    factory.create(config)
except Exception as e:
    if "Invalid `actor_id` type" in str(e):
        config["actor_id"] = str(config["actor_id"])
        factory.create(config)

Prevention

When it happens

Trigger: Passing `actor_id` in the actor config as something other than ActorId or str — e.g. an int, UUID object, None, or bytes — while constructing/registered a Python actor.

Common situations: Using a numeric or UUID id from another system as actor_id; YAML/JSON config where actor_id was loaded as an int; leaving actor_id set to None expecting it to be auto-generated.

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