{"record":{"id":"cc3fa7fad2a32e5e","repo":"tauri-apps/tauri","slug":"poisoned-window-resources-table-cc3fa7","errorCode":null,"errorMessage":"poisoned window resources table","messagePattern":"poisoned window resources table","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tauri/src/window/mod.rs","lineNumber":1072,"sourceCode":"  fn hash<H: Hasher>(&self, state: &mut H) {\n    self.window.label.hash(state)\n  }\n}\n\nimpl<R: Runtime> Eq for Window<R> {}\nimpl<R: Runtime> PartialEq for Window<R> {\n  /// Only use the [`Window`]'s label to compare equality.\n  fn eq(&self, other: &Self) -> bool {\n    self.window.label.eq(&other.window.label)\n  }\n}\n\nimpl<R: Runtime> Manager<R> for Window<R> {\n  fn resources_table(&self) -> MutexGuard<'_, ResourceTable> {\n    self\n      .resources_table\n      .lock()\n      .expect(\"poisoned window resources table\")\n  }\n}\n\nimpl<R: Runtime> ManagerBase<R> for Window<R> {\n  fn manager(&self) -> &AppManager<R> {\n    &self.manager\n  }\n\n  fn manager_owned(&self) -> Arc<AppManager<R>> {\n    self.manager.clone()\n  }\n\n  fn runtime(&self) -> RuntimeOrDispatch<'_, R> {\n    RuntimeOrDispatch::Dispatch(self.window.dispatcher.clone())\n  }\n\n  fn managed_app_handle(&self) -> &AppHandle<R> {\n    &self.app_handle","sourceCodeStart":1054,"sourceCodeEnd":1090,"githubUrl":"https://github.com/tauri-apps/tauri/blob/52e4b6e71d8632a7e648f866c442e287ecddee34/crates/tauri/src/window/mod.rs#L1054-L1090","documentation":"Window implements Manager::resources_table() by locking its own std::sync::Mutex around the ResourceTable and calling .expect(\"poisoned window resources table\"). Rust poisons a mutex when a thread panics while holding it, making every subsequent lock fail. This panic therefore reports that an earlier panic poisoned the Window's resource table; the message appears on the next resource access and repeats for every later one until the process ends.","triggerScenarios":"Any panic occurring while a thread holds this Window's resources-table mutex: a panicking Resource::drop (drops run while the table lock is held), a panic in plugin resource registration/lookup (fs, http), or a command/event handler that panics while holding a resources_table() guard. The 'poisoned window resources table' panic then fires on the next resource-related IPC for this Window.","commonSituations":"Custom resource types with panicking Drop impls; apps that stream large files and hit a mid-stream panic, after which all resource IPC on that window crashes; tauri/plugin version bumps that altered drop order; unwrapping resource lookups by rid in commands.","solutions":["Enable RUST_BACKTRACE=1 and find the FIRST panic in the log — it is the actual poisoner; this expect is downstream noise.","Remove every potential panic from Resource::drop and from code paths holding the resources_table() guard (replace unwrap/expect with error returns or logging).","Keep guards short-lived: fetch the Arc, drop the guard, then do fallible work.","Restart the application once fixed — the poisoned mutex never recovers in-process."],"exampleFix":"// before: unwrap inside Drop poisons the window resources table\nimpl Resource for TempBuffer {\n  fn drop(&mut self) {\n    std::fs::remove_file(&self.path).expect(\"temp file removed\");\n  }\n}\n\n// after: Drop must not panic\nimpl Resource for TempBuffer {\n  fn drop(&mut self) {\n    if let Err(e) = std::fs::remove_file(&self.path) {\n      log::warn!(\"failed to remove temp file {}: {e}\", self.path.display());\n    }\n  }\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"use std::panic::{catch_unwind, AssertUnwindSafe};\n\n// menu-independent guard: wrap resource-table access on Window so a\n// poisoned mutex degrades gracefully instead of crashing the thread\nmatch catch_unwind(AssertUnwindSafe(|| window.resources_table())) {\n  Ok(table) => { /* use the table */ }\n  Err(_) => {\n    log::error!(\"Window resource table poisoned — restart required\");\n  }\n}","preventionTips":["Keep Drop impls of custom resources free of unwrap/expect and I/O panics.","Log the first panic via std::panic::set_hook so poisoning is diagnosable from the real root cause.","Scope resource-table guards to the shortest possible block; never across await points or fallible calls.","Audit commands that look up resources by rid and return Result instead of unwrapping."],"tags":["rust","mutex","poisoning","panic","resources","window","manager"],"backgroundTag":"mutex-poisoning","analyzedSha":"52e4b6e71d8632a7e648f866c442e287ecddee34","analyzedAt":"2026-08-20T13:59:20.734Z","schemaVersion":2},"datasetVersion":"2026-08-31T22:30:34.772Z"}