{"record":{"id":"93c5addb651d4b68","repo":"astral-sh/ruff","slug":"initlogging-to-only-be-called-at-most-once","errorCode":null,"errorMessage":"`initLogging` to only be called at most once.","messagePattern":"`initLogging` to only be called at most once\\.","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/ruff_wasm/src/lib.rs","lineNumber":243,"sourceCode":"\n    // When the `console_error_panic_hook` feature is enabled, we can call the\n    // `set_panic_hook` function at least once during initialization, and then\n    // we will get better error messages if our code ever panics.\n    //\n    // For more details see\n    // https://github.com/rustwasm/console_error_panic_hook#readme\n    #[cfg(feature = \"console_error_panic_hook\")]\n    console_error_panic_hook::set_once();\n}\n\n/// Initializes the logger with the given log level.\n///\n/// ## Panics\n/// If this function is called more than once.\n#[wasm_bindgen(js_name = \"initLogging\")]\npub fn init_logging(level: LogLevel) {\n    console_log::init_with_level(level.into())\n        .expect(\"`initLogging` to only be called at most once.\");\n}\n\n#[derive(Copy, Clone, Debug)]\n#[wasm_bindgen]\npub enum LogLevel {\n    Trace,\n    Debug,\n    Info,\n    Warn,\n    Error,\n}\n\nimpl From<LogLevel> for log::Level {\n    fn from(level: LogLevel) -> Self {\n        match level {\n            LogLevel::Trace => log::Level::Trace,\n            LogLevel::Debug => log::Level::Debug,\n            LogLevel::Info => log::Level::Info,","sourceCodeStart":225,"sourceCodeEnd":261,"githubUrl":"https://github.com/astral-sh/ruff/blob/d1087a4b9e03d253a88703f34e0869ee4b805456/crates/ruff_wasm/src/lib.rs#L225-L261","documentation":"initLogging initializes console_log for the ruff WASM build; console_log::init_with_level errors if a logger is already installed, and the .expect turns that into a panic: '`initLogging` to only be called at most once.' (documented under ## Panics).","triggerScenarios":"Calling the exported initLogging twice within one WASM instance - React StrictMode double-mount, hot-module reload re-running bootstrap, or two init code paths both executing.","commonSituations":"Playground/embedding setups that re-initialize on settings change; duplicated init logic in bundler entry points; HMR during development.","solutions":["Call initLogging exactly once during app bootstrap","Guard with a module-level flag so repeat invocations are ignored","On reconfiguration, keep the existing logger rather than re-initializing it"],"exampleFix":"// before\nexport function boot(level) { initLogging(level); } // called twice -> panic\n\n// after\nlet loggingReady = false;\nexport function boot(level) {\n  if (!loggingReady) { initLogging(level); loggingReady = true; }\n}","handlingStrategy":"validation","validationCode":"let loggingInitialized = false;\nfunction boot(level) {\n  if (loggingInitialized) return;\n  initLogging(level);\n  loggingInitialized = true;\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Initialize logging exactly once in app bootstrap, outside React component lifecycles","Guard re-init paths (HMR, StrictMode) with a module-level flag","Recreate the WASM instance rather than re-initializing its logger"],"tags":["wasm","logging","initialization","panic"],"backgroundTag":"double-initialization","analyzedSha":"d1087a4b9e03d253a88703f34e0869ee4b805456","analyzedAt":"2026-08-20T16:33:49.445Z","contentChangedAt":"2026-08-20T16:33:49.445Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}