nautechsystems/nautilus_trader · error

Actor type mismatch for '{id}': expected {expected_type:?},

Error message

Actor type mismatch for '{id}': expected {expected_type:?}, found {actual_type:?}

What it means

get_actor_unchecked first finds an actor by id, then downcasts its ActorRef to the requested type T. If an actor with the id exists but its concrete type differs from T, the function panics with the expected vs actual type names. 'Unchecked' refers to both existence and type assumptions being unchecked by the caller.

Source

Thrown at crates/common/src/actor/registry.rs:217

/// The returned [`ActorRef`] holds an `Rc` to keep the actor alive, preventing
/// use-after-free if the actor is removed from the registry.
///
/// # Panics
///
/// - Panics if no actor with the specified `id` is found in the registry.
/// - Panics if the stored actor is not of type `T`.
#[must_use]
pub fn get_actor_unchecked<T: Actor>(id: &Ustr) -> ActorRef<T> {
    let actor_rc = with_actor_registry(|registry| registry.get(id))
        .unwrap_or_else(|| panic!("Actor for {id} not found"));

    match actor_ref_from_rc(actor_rc) {
        Ok(actor_ref) => actor_ref,
        Err(ActorRefError {
            expected_type,
            actual_type,
        }) => {
            panic!(
                "Actor type mismatch for '{id}': expected {expected_type:?}, found {actual_type:?}"
            )
        }
    }
}

/// Attempts to get a guard providing mutable access to the registered actor.
///
/// Returns `None` if the actor is not found or the type doesn't match.
#[must_use]
pub fn try_get_actor_unchecked<T: Actor>(id: &Ustr) -> Option<ActorRef<T>> {
    let actor_rc = with_actor_registry(|registry| registry.get(id))?;
    actor_ref_from_rc(actor_rc).ok()
}

#[derive(Debug)]
struct ActorRefError {
    expected_type: TypeId,

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Check the actual type in the panic message and request that type (or a compatible one) in get_actor_unchecked::<T>
  2. Ensure only one actor kind is registered under each id
  3. Use the checked API that returns Result<ActorRef<T>, ActorRefError> to handle mismatches gracefully
  4. Update call sites after refactoring an actor's concrete type

Example fix

// before
let actor = get_actor_unchecked::<DataActor>(&ustr("quotes"));
// after
let actor = get_actor_unchecked::<RiskActor>(&ustr("quotes")); // request actual type per panic message
Defensive patterns

Strategy: validation

Validate before calling

let actor = registry.get(&id).expect("actor registered");
// confirm concrete type before unchecked downcast via a checked API returning Result

Prevention

When it happens

Trigger: Calling get_actor_unchecked::<SomeActor>(id) where the id maps to an actor of a different concrete type, e.g. two actor kinds registered under the same id, or the actor's type changed after a refactor.

Common situations: Registering a test double/mock under the same id as the production actor type; refactoring an actor's type without updating callers of get_actor_unchecked; generic code parameterized with the wrong Actor type argument.

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