{"record":{"id":"4551d824f49d6a92","repo":"gfx-rs/wgpu","slug":"accessing-the-gpu-is-only-supported-on-the-main-th","errorCode":null,"errorMessage":"Accessing the GPU is only supported on the main thread or from a dedicated worker","messagePattern":"Accessing the GPU is only supported on the main thread or from a dedicated worker","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"wgpu/src/backend/webgpu.rs","lineNumber":1651,"sourceCode":"crate::cmp::impl_eq_ord_hash_proxy!(WebPipelineCache => .ident);\ncrate::cmp::impl_eq_ord_hash_proxy!(WebCommandEncoder => .ident);\ncrate::cmp::impl_eq_ord_hash_proxy!(WebComputePassEncoder => .ident);\ncrate::cmp::impl_eq_ord_hash_proxy!(WebRenderPassEncoder => .ident);\ncrate::cmp::impl_eq_ord_hash_proxy!(WebCommandBuffer => .ident);\ncrate::cmp::impl_eq_ord_hash_proxy!(WebRenderBundleEncoder => .ident);\ncrate::cmp::impl_eq_ord_hash_proxy!(WebRenderBundle => .ident);\ncrate::cmp::impl_eq_ord_hash_proxy!(WebSurface => .ident);\ncrate::cmp::impl_eq_ord_hash_proxy!(WebSurfaceOutputDetail => .ident);\ncrate::cmp::impl_eq_ord_hash_proxy!(WebQueueWriteBuffer => .ident);\ncrate::cmp::impl_eq_ord_hash_proxy!(WebBufferMappedRange => .ident);\n\nimpl dispatch::InstanceInterface for ContextWebGpu {\n    fn new(desc: crate::InstanceDescriptor) -> Self\n    where\n        Self: Sized,\n    {\n        let Ok(gpu) = get_browser_gpu_property() else {\n            panic!(\n                \"Accessing the GPU is only supported on the main thread or from a dedicated worker\"\n            );\n        };\n\n        ContextWebGpu {\n            gpu,\n            requested_backends: desc.backends,\n            ident: crate::cmp::Identifier::create(),\n        }\n    }\n\n    unsafe fn create_surface(\n        &self,\n        target: crate::SurfaceTargetUnsafe,\n    ) -> Result<dispatch::DispatchSurface, crate::CreateSurfaceError> {\n        match target {\n            SurfaceTargetUnsafe::RawHandle {\n                raw_display_handle: _,","sourceCodeStart":1633,"sourceCodeEnd":1669,"githubUrl":"https://github.com/gfx-rs/wgpu/blob/3e11ff59bf3f9795d285ecc045014089640d7248/wgpu/src/backend/webgpu.rs#L1633-L1669","documentation":"ContextWebGpu::new panics when navigator.gpu (or the worker-equivalent) cannot be retrieved via get_browser_gpu_property. WebGPU is only accessible on the main thread or inside a dedicated Web Worker; shared workers, service workers, and non-browser environments have no GPU object. wgpu panics at instance creation because the whole backend is unusable without it.","triggerScenarios":"Calling wgpu::Instance::new (or creating a ContextWebGpu) from a shared worker or service worker, from a thread without navigator.gpu, or in an environment where navigator.gpu is undefined (no WebGPU support / insecure context).","commonSituations":"Running WASM code inside a Service Worker (e.g. offline processing); older browsers without WebGPU; serving over plain HTTP instead of HTTPS (WebGPU requires a secure context); creating the instance on a spawned non-dedicated worker thread.","solutions":["Create the wgpu Instance on the main thread or in a DedicatedWorker and pass resources/handles as needed.","Check 'gpu' in navigator (and window.isSecureContext) before instantiating and fall back to another backend or show a support message.","Serve the app over HTTPS/localhost and use a browser with WebGPU enabled (Chrome 113+, Edge, recent Firefox/Safari)."],"exampleFix":"// before\nlet instance = wgpu::Instance::new(&wgpu::InstanceDescriptor::default()); // panics in service worker\n// after (main thread)\nif (!(\"gpu\" in navigator) || !window.isSecureContext) { throw new Error(\"WebGPU unavailable\"); }\nlet instance = wgpu::Instance::new(&wgpu::InstanceDescriptor::default());","handlingStrategy":"validation","validationCode":"// run before creating an Instance on web\nif js_sys::Reflect::get(&web_sys::window().unwrap().navigator(), &\"gpu\".into()).is_err() || !js_sys::eval(\"window.isSecureContext\").unwrap().is_truthy() {\n    panic!(\"WebGPU unavailable: need main thread or dedicated worker, secure context, WebGPU-capable browser\");\n}","typeGuard":"fn webgpu_available(navigator: &web_sys::Navigator) -> bool {\n    js_sys::Reflect::has(navigator.as_ref(), &\"gpu\".into()).unwrap_or(false)\n}","tryCatchPattern":null,"preventionTips":["Create the wgpu Instance only on the main thread or in a DedicatedWorker.","Serve over HTTPS or localhost (secure context required).","Feature-detect navigator.gpu before any wgpu initialization and provide a fallback message/backend."],"tags":["webgpu","wasm","browser","threading","environment"],"backgroundTag":"webgpu-unavailable-in-context","analyzedSha":"3e11ff59bf3f9795d285ecc045014089640d7248","analyzedAt":"2026-09-03T01:43:21.459Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T07:17:11.731Z"}