tauri-apps/tauri · critical

poisoned WebContext store

Error message

poisoned WebContext store

What it means

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.

Solutions

  1. Fix the original panic that poisoned the lock — look for the first panic in the logs.
  2. Avoid creating webviews/windows from multiple threads; route creation through the main thread/event loop.
  3. Avoid unwraps in code paths that touch the web context store.

Example fix

// before
std::thread::spawn(|| app.create_webview(...));

// after
app.run_on_main_thread(move || app.create_webview(...));
Defensive patterns

Strategy: try-catch

Try / catch

// contain panics from webview creation so they cannot poison shared state
let res = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
  app.create_webview(...)
}));
if res.is_err() { eprintln!("webview creation panicked"); }

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of tauri-apps/tauri@460ec35447 (2026-09-18). Data as JSON: /api/errors/036e834c258f19aa. Report an issue: GitHub.

Appendix: source

Thrown at crates/tauri-runtime-wry/src/lib.rs:4683

      return Err(Error::WebviewRuntimeNotInstalled);
    }
  }

  #[allow(unused_mut)]
  let PendingWebview {
    webview_attributes,
    uri_scheme_protocols,
    label,
    ipc_handler,
    url,
    ..
  } = pending;

  let mut web_context = context
    .main_thread
    .web_context
    .lock()
    .expect("poisoned WebContext store");
  let is_first_context = web_context.is_empty();
  // the context must be stored on the HashMap because it must outlive the WebView on macOS
  let automation_enabled = std::env::var("TAURI_WEBVIEW_AUTOMATION").as_deref() == Ok("true");
  let web_context_key = webview_attributes.data_directory;
  let entry = web_context.entry(web_context_key.clone());
  let web_context = match entry {
    Occupied(occupied) => {
      let occupied = occupied.into_mut();
      occupied.referenced_by_webviews.insert(label.clone());
      occupied
    }
    Vacant(vacant) => {
      let mut web_context = WryWebContext::new(web_context_key.clone());
      web_context.set_allows_automation(if automation_enabled {
        is_first_context
      } else {
        false
      });

View on GitHub (pinned to 460ec35447)