nautechsystems/nautilus_trader · error

Event '{}' should have associated handler

Error message

Event '{}' should have associated handler

What it means

LiveClock::get_handler resolves the callback for a TimeEvent by its event name, panicking when neither a named callback nor a default callback was registered for that name. Timers created with a name expect a matching set_callback(name, ...) registration before the timer fires.

Source

Thrown at crates/common/src/clock.rs:769

    /// Returns the callback for `name`, falling back to the default callback.
    #[must_use]
    pub fn get_callback(&self, name: &Ustr) -> Option<TimeEventCallback> {
        self.callbacks
            .get(name)
            .cloned()
            .or_else(|| self.default_callback.clone())
    }

    /// Creates a handler for `event` using its named callback or the default callback.
    ///
    /// # Panics
    ///
    /// Panics if neither a named nor default callback exists for the event.
    #[must_use]
    pub fn get_handler(&self, event: TimeEvent) -> TimeEventHandler {
        let callback = self
            .get_callback(&event.name)
            .unwrap_or_else(|| panic!("Event '{}' should have associated handler", event.name));

        TimeEventHandler::new(event, callback)
    }

    /// Clears all named callbacks, preserving the default callback.
    pub fn clear(&mut self) {
        self.callbacks.clear();
    }
}

/// Validates and normalizes parameters for a time alert.
///
/// `allow_past` defaults to `true`. When enabled, a past alert timestamp is replaced with
/// `ts_now`. Returns the interned name and normalized alert timestamp.
///
/// # Errors
///
/// Returns an error if `name` is invalid or the alert is in the past when past alerts are

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Register a callback for the exact event name with set_callback before the timer can fire
  2. Register a default callback so unmatched named events still have a handler
  3. Do not call clear() while timers with named callbacks are still pending, or re-register callbacks after clearing
  4. Verify the timer name string matches the callback name exactly

Example fix

// before
clock.set_timer("my-timer", interval);
// after
clock.set_timer("my-timer", interval);
clock.set_callback("my-timer", Box::new(|event| { /* handle */ }));
Defensive patterns

Strategy: validation

Validate before calling

// before scheduling, ensure a callback exists for the name
clock.set_callback("my-timer", Box::new(handle_event));
clock.set_timer("my-timer", interval);

Prevention

When it happens

Trigger: Registering a timer with set_timer(name, ...) (or set_time_alert) but never calling set_callback with the same name; calling clear() which removes named callbacks while timers are still pending; a name mismatch between timer registration and callback registration.

Common situations: Actor restart/reconnect paths that clear callbacks but leave timers scheduled; renaming a timer in one place but not the callback registration; timers left running during shutdown when the event still fires.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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