{"record":{"id":"036e834c258f19aa","repo":"tauri-apps/tauri","slug":"poisoned-webcontext-store","errorCode":null,"errorMessage":"poisoned WebContext store","messagePattern":"poisoned WebContext store","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"crates/tauri-runtime-wry/src/lib.rs","lineNumber":4683,"sourceCode":"      return Err(Error::WebviewRuntimeNotInstalled);\n    }\n  }\n\n  #[allow(unused_mut)]\n  let PendingWebview {\n    webview_attributes,\n    uri_scheme_protocols,\n    label,\n    ipc_handler,\n    url,\n    ..\n  } = pending;\n\n  let mut web_context = context\n    .main_thread\n    .web_context\n    .lock()\n    .expect(\"poisoned WebContext store\");\n  let is_first_context = web_context.is_empty();\n  // the context must be stored on the HashMap because it must outlive the WebView on macOS\n  let automation_enabled = std::env::var(\"TAURI_WEBVIEW_AUTOMATION\").as_deref() == Ok(\"true\");\n  let web_context_key = webview_attributes.data_directory;\n  let entry = web_context.entry(web_context_key.clone());\n  let web_context = match entry {\n    Occupied(occupied) => {\n      let occupied = occupied.into_mut();\n      occupied.referenced_by_webviews.insert(label.clone());\n      occupied\n    }\n    Vacant(vacant) => {\n      let mut web_context = WryWebContext::new(web_context_key.clone());\n      web_context.set_allows_automation(if automation_enabled {\n        is_first_context\n      } else {\n        false\n      });","sourceCodeStart":4665,"sourceCodeEnd":4701,"githubUrl":"https://github.com/tauri-apps/tauri/blob/460ec35447493200d64290dd7f015d5a91d0fd58/crates/tauri-runtime-wry/src/lib.rs#L4665-L4701","documentation":"During webview/window creation, the runtime locks the shared `WebContext` store mutex. If another thread panicked while holding that lock, the mutex is poisoned and every later `.lock().expect(...)` panics with this message.","triggerScenarios":"Any webview/window creation after a panic occurred in code that held the `web_context` mutex — most likely inside earlier webview creation or context-store manipulation on another thread.","commonSituations":"A first webview-creation panic (e.g. another `expect` in the same create-path) poisoning the store; multi-window apps creating windows concurrently; automation mode (`TAURI_WEBVIEW_AUTOMATION=true`) exercising rarer paths.","solutions":["Fix the original panic that poisoned the lock — look for the first panic in the logs.","Avoid creating webviews/windows from multiple threads; route creation through the main thread/event loop.","Avoid unwraps in code paths that touch the web context store."],"exampleFix":"// before\nstd::thread::spawn(|| app.create_webview(...));\n\n// after\napp.run_on_main_thread(move || app.create_webview(...));","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"// contain panics from webview creation so they cannot poison shared state\nlet res = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {\n  app.create_webview(...)\n}));\nif res.is_err() { eprintln!(\"webview creation panicked\"); }","preventionTips":["Never panic inside code that runs while holding locks.","Create all webviews/windows on the main thread.","Check logs for the FIRST panic — poisoning is always a secondary symptom."],"tags":["mutex","poisoned-lock","panic","webview","threading"],"backgroundTag":"internal-invariant-violation","analyzedSha":"460ec35447493200d64290dd7f015d5a91d0fd58","analyzedAt":"2026-09-18T23:55:51.277Z","contentChangedAt":"2026-09-18T23:55:51.277Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}