{"record":{"id":"ecff8b0ab3ba1c31","repo":"nautechsystems/nautilus_trader","slug":"python-on-time-event-failed-e-ecff8b","errorCode":null,"errorMessage":"Python on_time_event failed: {e}","messagePattern":"Python on_time_event failed: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/trading/src/python/algorithm.rs","lineNumber":586,"sourceCode":"    fn on_dispose(&mut self) -> anyhow::Result<()> {\n        self.dispatch_no_args(\"on_dispose\")\n            .map_err(|e| anyhow::anyhow!(\"Python on_dispose failed: {e}\"))\n    }\n\n    fn on_degrade(&mut self) -> anyhow::Result<()> {\n        self.dispatch_no_args(\"on_degrade\")\n            .map_err(|e| anyhow::anyhow!(\"Python on_degrade failed: {e}\"))\n    }\n\n    fn on_fault(&mut self) -> anyhow::Result<()> {\n        self.dispatch_no_args(\"on_fault\")\n            .map_err(|e| anyhow::anyhow!(\"Python on_fault failed: {e}\"))\n    }\n\n    fn on_time_event(&mut self, event: &TimeEvent) -> anyhow::Result<()> {\n        ExecutionAlgorithm::on_time_event(self, event)?;\n        self.dispatch_time_event(event)\n            .map_err(|e| anyhow::anyhow!(\"Python on_time_event failed: {e}\"))\n    }\n\n    fn on_signal(&mut self, signal: &Signal) -> anyhow::Result<()> {\n        self.dispatch_on_signal(signal)\n            .map_err(|e| anyhow::anyhow!(\"Python on_signal failed: {e}\"))\n    }\n\n    fn on_queue_state(&mut self, event: &QueueStateChanged) -> anyhow::Result<()> {\n        self.dispatch_on_queue_state(event)\n            .map_err(|e| anyhow::anyhow!(\"Python on_queue_state failed: {e}\"))\n    }\n\n    fn on_socket_state(&mut self, event: &SocketStateChanged) -> anyhow::Result<()> {\n        self.dispatch_on_socket_state(event)\n            .map_err(|e| anyhow::anyhow!(\"Python on_socket_state failed: {e}\"))\n    }\n}\n","sourceCodeStart":568,"sourceCodeEnd":604,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/trading/src/python/algorithm.rs#L568-L604","documentation":"Raised by the Rust `ExecutionAlgorithm` wrapper when the Python callback `on_time_event` throws an exception. The wrapper first runs the native Rust `ExecutionAlgorithm::on_time_event`, then dispatches the `TimeEvent` into the Python subclass via `dispatch_time_event`; a `PyErr` from the user's handler is wrapped in `anyhow!(\"Python on_time_event failed: {e}\")`.","triggerScenarios":"A registered timer fires and the trader calls `on_time_event(event)`; the user's Python subclass overrides `on_time_event` and raises (e.g. mishandles the event type, wrong event class assumed, or an exception inside timed logic). Also triggered by `algo.on_time_event(event)` called directly with a `TimeEvent`.","commonSituations":"Timers set with `clock.set_timer` whose handlers unpack event fields that don't exist after a version change; logic assuming a specific `TimeEvent` name/tag; unhandled exceptions inside backtest loops at timer expiry.","solutions":["Inspect the embedded Python traceback in the error to locate the failing line in your `on_time_event` override","Handle the incoming `TimeEvent` generically (check `event.name`/`event.tags`) instead of assuming a specific timer","Add try/except inside `on_time_event` for expected data conditions and log the failure","Confirm the override signature is `def on_time_event(self, event) -> None:`","Re-register or cancel stale timers in `on_stop`/`on_fault` so no handler fires against torn-down state"],"exampleFix":"# before\ndef on_time_event(self, event):\n    price = self.cache.price(self.instrument_id)  # raises if no price yet\n\n# after\ndef on_time_event(self, event):\n    price = self.cache.price(self.instrument_id)\n    if price is None:\n        self.log.warning(f\"No price yet for {event.name}\")\n        return","handlingStrategy":"try-catch","validationCode":"sig = inspect.signature(MyAlgo.on_time_event)\nassert list(sig.parameters) == ['self', 'event']","typeGuard":"def is_time_event(ev):\n    return hasattr(ev, 'ts_event') and hasattr(ev, 'name')  # TimeEvent surface","tryCatchPattern":"try:\n    algo.on_time_event(event)\nexcept Exception as e:\n    log.error(f\"on_time_event failed for timer '{event.name}': {e}\")","preventionTips":["Handle events by timer name/tag defensively; never assume a specific event type","Cancel timers in `on_stop` so handlers cannot fire after teardown","Avoid cache/network lookups in timer handlers without null checks","Unit-test timer handlers with representative `TimeEvent` fixtures"],"tags":["python","callback","timer","rust","execution-algorithm"],"backgroundTag":"api-error-response","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}