{"record":{"id":"a5f0e6e883a407f1","repo":"nautechsystems/nautilus_trader","slug":"failed-to-create-logguard-from-global-sender","errorCode":null,"errorMessage":"Failed to create LogGuard from global sender","messagePattern":"Failed to create LogGuard from global sender","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/common/src/logging/logger.rs","lineNumber":1035,"sourceCode":"            // and force the bypass flag so subsequent log calls no-op without\n            // SendError noise.\n            let _ = (trader_id, instance_id, config, file_config, rx);\n            super::logging_set_bypass();\n        }\n\n        let max_level = log::LevelFilter::Trace;\n        set_max_level(max_level);\n\n        if print_config {\n            println!(\"Logger set as `log` implementation with max level {max_level}\");\n        }\n\n        super::LOGGING_INITIALIZED.store(true, Ordering::SeqCst);\n        super::LOGGING_COLORED.store(is_colored, Ordering::SeqCst);\n        *lifecycle = LoggerLifecycle::Running;\n\n        LogGuard::new_locked()\n            .ok_or_else(|| anyhow::anyhow!(\"Failed to create LogGuard from global sender\"))\n    }\n\n    #[cfg(not(all(feature = \"simulation\", madsim)))]\n    #[expect(clippy::needless_pass_by_value)]\n    fn handle_messages(\n        trader_id: String,\n        instance_id: String,\n        config: LoggerConfig,\n        file_config: FileWriterConfig,\n        rx: std::sync::mpsc::Receiver<LogEvent>,\n    ) {\n        let LoggerConfig {\n            stdout_level,\n            fileout_level,\n            component_level: _,\n            module_level: _,\n            log_components_only: _,\n            is_colored,","sourceCodeStart":1017,"sourceCodeEnd":1053,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/common/src/logging/logger.rs#L1017-L1053","documentation":"In the non-(simulation+madsim) init path, after spawning the logger thread and setting LOGGING_INITIALIZED, the code creates the LogGuard that owns the global sender via `LogGuard::new_locked()`. If that returns None (guard state could not be established from the just-created global sender) it aborts with this error — logging was configured but a valid owner handle could not be produced.","triggerScenarios":"First-time logger initialization where LogGuard::new_locked() fails to attach to the global sender — typically caused by broken internal static state (e.g. statics reset after fork, re-entrant init from a signal/atexit handler, or a prior init panicking mid-way leaving inconsistent globals).","commonSituations":"Fork-after-init in multiprocess setups (child inherits inconsistent statics); double init racing in threads without synchronization; embedding nautilus in a runtime that re-executes module init; OOM or panic during logger thread startup.","solutions":["Initialize logging once, early, on the main thread before any fork/thread spawn.","If using multiprocessing/fork, initialize logging in each child after fork rather than inheriting state.","Check for earlier panics or poisoned statics in the logging module; restart the process if globals are inconsistent.","Ensure only one call path initializes logging (avoid both Python init_logging and Rust init racing)."],"exampleFix":"// before\nspawn_worker();        // forks after logging init\ninit_logging(...)?;    // child hits failed guard here\n// after\nspawn_worker_with(|| {\n    let guard = init_logging(...)?; // init inside child\n    run(guard)\n});","handlingStrategy":"try-catch","validationCode":"// Rust: detect inconsistent logging statics before init\nif LOGGING_INITIALIZED.load(Ordering::SeqCst) && LOGGER_LIFECYCLE.lock() != Running {\n    // statics inconsistent; avoid init path that builds a guard from sender\n}","typeGuard":"fn guard_available() -> bool { LogGuard::peek_locked().is_some() }","tryCatchPattern":"let guard = LogGuard::new_locked().ok_or_else(|| {\n    anyhow::anyhow!(\"Failed to create LogGuard from global sender; restart process\")\n})?;","preventionTips":["Init logging on the main thread before spawning threads or forking.","Re-initialize logging inside forked children rather than inheriting statics.","Ensure a single init code path; avoid racing Python and Rust init calls.","Investigate any earlier panic in logger startup, which can leave statics half-built."],"tags":["rust","logging","lifecycle","initialization"],"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"}