{"record":{"id":"9af7918212639ccc","repo":"nautechsystems/nautilus_trader","slug":"python-on-start-failed-e","errorCode":null,"errorMessage":"Python on_start failed: {e}","messagePattern":"Python on_start failed: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/common/src/python/actor.rs","lineNumber":1020,"sourceCode":"pub fn register_python_exec_algorithm_endpoint(exec_algorithm_id: ExecAlgorithmId) {\n    let actor_id = exec_algorithm_id.inner();\n    let endpoint: Ustr = format!(\"{exec_algorithm_id}.execute\").into();\n    let handler = ShareableMessageHandler::from_typed(move |command: &TradingCommand| {\n        if let Some(mut algo) = try_get_actor_unchecked::<PyDataActorInner>(&actor_id) {\n            if let Err(e) = algo.execute_exec_algorithm_command(command) {\n                log::error!(\"Error executing command on Python algorithm {actor_id}: {e}\");\n            }\n        } else {\n            log::error!(\"Python execution algorithm {actor_id} not found in registry\");\n        }\n    });\n    msgbus::register_any(endpoint.into(), handler);\n}\n\nimpl DataActor for PyDataActorInner {\n    fn on_start(&mut self) -> anyhow::Result<()> {\n        self.dispatch_on_start()\n            .map_err(|e| anyhow::anyhow!(\"Python on_start failed: {e}\"))\n    }\n\n    fn on_stop(&mut self) -> anyhow::Result<()> {\n        self.dispatch_on_stop()\n            .map_err(|e| anyhow::anyhow!(\"Python on_stop failed: {e}\"))\n    }\n\n    fn on_resume(&mut self) -> anyhow::Result<()> {\n        self.dispatch_on_resume()\n            .map_err(|e| anyhow::anyhow!(\"Python on_resume failed: {e}\"))\n    }\n\n    fn on_reset(&mut self) -> anyhow::Result<()> {\n        self.dispatch_on_reset()\n            .map_err(|e| anyhow::anyhow!(\"Python on_reset failed: {e}\"))\n    }\n\n    fn on_dispose(&mut self) -> anyhow::Result<()> {","sourceCodeStart":1002,"sourceCodeEnd":1038,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/common/src/python/actor.rs#L1002-L1038","documentation":"PyDataActorInner::on_start forwards to the actor's Python on_start override via dispatch_on_start; any Python exception in that handler is wrapped as this anyhow error. It means the actor failed during its start lifecycle, typically preventing the actor/trading node from starting correctly.","triggerScenarios":"An actor (often an exec algorithm or custom DataActor) is started and its Python on_start implementation raises — e.g. subscribing to a bad topic, requesting data with wrong parameters, or touching uninitialized state.","commonSituations":"Configuration mistakes surfaced at startup (missing instrument IDs, wrong client IDs), subscribing before the cache is populated, network/API calls in on_start failing, or code assuming config keys that were not provided.","solutions":["Read the wrapped '{e}' cause to identify the original Python exception in on_start","Validate config/instrument IDs and required clients at the top of on_start and fail fast with clear messages","Move long-running or error-prone work out of on_start into timers/handlers where failures are recoverable","Cover actor startup in a backtest/integration test so on_start bugs surface before live deployment"],"exampleFix":"# before\ndef on_start(self):\n    self.subscribe_quote_ticks(InstrumentId.from_str(self.config.instrument))  # None/invalid raises\n# after\ndef on_start(self):\n    if not self.config.instrument:\n        self.log.error(\"instrument not configured\")\n        self.stop()\n        return\n    self.subscribe_quote_ticks(InstrumentId.from_str(self.config.instrument))","handlingStrategy":"try-catch","validationCode":"def validate_config(config) -> list[str]:\n    errors = []\n    if not getattr(config, \"instrument\", None):\n        errors.append(\"instrument is required\")\n    if not getattr(config, \"client_id\", None):\n        errors.append(\"client_id is required\")\n    return errors\n\n# call at the top of on_start; stop the actor if non-empty","typeGuard":"def config_ok(self) -> bool:\n    return bool(getattr(self.config, \"instrument\", None)) and bool(\n        getattr(self.config, \"client_id\", None)\n    )","tryCatchPattern":"def on_start(self):\n    try:\n        self._do_start()\n    except Exception as e:\n        self.log.exception(f\"startup failed: {e}\")\n        self.stop()\n        raise  # re-raise only if the node must refuse to start","preventionTips":["Validate all config fields before touching the bus/cache in on_start","Never perform blocking I/O or fragile external calls directly in on_start","Add an integration test that starts every actor against a populated cache","Fail fast with explicit error messages instead of letting deep exceptions surface as 'Python on_start failed'"],"tags":["python","actor","lifecycle","on-start"],"backgroundTag":"internal-invariant-violation","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}