{"record":{"id":"594dbde27132a265","repo":"gfx-rs/wgpu","slug":"could-not-create-shader-594dbd","errorCode":null,"errorMessage":"Could not create shader","messagePattern":"Could not create shader","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"wgpu-hal/src/gles/web.rs","lineNumber":324,"sourceCode":"                    swapchain.extent.width as i32,\n                    0,\n                    0,\n                    0,\n                    swapchain.extent.width as i32,\n                    swapchain.extent.height as i32,\n                    glow::COLOR_BUFFER_BIT,\n                    glow::NEAREST,\n                )\n            };\n        }\n\n        Ok(())\n    }\n\n    unsafe fn create_srgb_present_program(gl: &glow::Context) -> glow::Program {\n        let program = unsafe { gl.create_program() }.expect(\"Could not create shader program\");\n        let vertex =\n            unsafe { gl.create_shader(glow::VERTEX_SHADER) }.expect(\"Could not create shader\");\n        unsafe { gl.shader_source(vertex, include_str!(\"./shaders/srgb_present.vert\")) };\n        unsafe { gl.compile_shader(vertex) };\n        let fragment =\n            unsafe { gl.create_shader(glow::FRAGMENT_SHADER) }.expect(\"Could not create shader\");\n        unsafe { gl.shader_source(fragment, include_str!(\"./shaders/srgb_present.frag\")) };\n        unsafe { gl.compile_shader(fragment) };\n        unsafe { gl.attach_shader(program, vertex) };\n        unsafe { gl.attach_shader(program, fragment) };\n        unsafe { gl.link_program(program) };\n        unsafe { gl.delete_shader(vertex) };\n        unsafe { gl.delete_shader(fragment) };\n        unsafe { gl.bind_texture(glow::TEXTURE_2D, None) };\n\n        program\n    }\n\n    pub fn supports_srgb(&self) -> bool {\n        // present.frag takes care of handling srgb conversion","sourceCodeStart":306,"sourceCodeEnd":342,"githubUrl":"https://github.com/gfx-rs/wgpu/blob/3e11ff59bf3f9795d285ecc045014089640d7248/wgpu-hal/src/gles/web.rs#L306-L342","documentation":"This panic fires in `create_srgb_present_program` when `gl.create_shader(glow::VERTEX_SHADER)` returns a null shader object while building the internal sRGB-present vertex shader on the WebGL/GLES backend. A null shader means the WebGL implementation refused to allocate a shader object, almost always due to context loss or exceeding the shader object limit. The panic aborts instance/device creation.","triggerScenarios":"wgpu instance/device initialization on the web backend, specifically the first `gl.create_shader(VERTEX_SHADER)` call inside `create_srgb_present_program`, when the WebGL context has been lost, the context is no longer current, or the driver/browser cannot allocate more shader objects.","commonSituations":"Pages that accumulate many contexts (each canvas/context has its own object budget); webglcontextlost fired by browser GPU-process reset; running inside iframes or headless browsers where WebGL fallback to SwiftShader runs out of resources; hidden-tab throttling leading to context loss between frames.","solutions":["Listen for `webglcontextlost` (call `event.preventDefault()`) and fully re-create the wgpu Instance/Device/Surface after `webglcontextrestored`.","Cut down context and shader object count: share one device across the app and destroy unused surfaces.","Confirm the context is healthy before creating wgpu: `canvas.getContext('webgl2')` plus `gl.isContextLost()` check.","Test on a different browser/driver to rule out GPU-driver-specific allocation failure; enable hardware acceleration."],"exampleFix":"// before\nlet vertex = unsafe { gl.create_shader(glow::VERTEX_SHADER) }.expect(\"Could not create shader\");\n// after\nlet vertex = unsafe { gl.create_shader(glow::VERTEX_SHADER) }\n    .ok_or(crate::CreateDeviceError::ResourceCreationFailed)?;","handlingStrategy":"try-catch","validationCode":"const gl = canvas.getContext('webgl2');\nif (!gl) throw new Error('WebGL2 unsupported');\nif (gl.isContextLost()) throw new Error('WebGL2 context lost');\n// sanity: shader object creation works\nconst probe = gl.createShader(gl.VERTEX_SHADER);\nif (!probe) throw new Error('Cannot allocate shader objects');\ngl.deleteShader(probe);","typeGuard":"function contextCanAllocateShaders(gl: WebGL2RenderingContext | null): gl is WebGL2RenderingContext {\n  if (!gl || gl.isContextLost()) return false;\n  const s = gl.createShader(gl.VERTEX_SHADER);\n  if (!s) return false;\n  gl.deleteShader(s);\n  return true;\n}","tryCatchPattern":"try {\n  const adapter = await navigator.gpu.requestAdapter();\n  const device = await adapter.requestDevice();\n  device.lost.then(info => { if (info.reason !== 'destroyed') reinitWgpu(); });\n} catch (e) {\n  renderStaticFallback();\n}","preventionTips":["Track device.lost (WebGPU) and webglcontextlost (WebGL) and rebuild the whole pipeline on loss.","Avoid hammering instance creation in retry loops without backoff; repeated failed creations worsen resource exhaustion.","Test in headless/SwiftShader environments early since they have tighter resource budgets.","Destroy unused surfaces/textures so shader and program object budgets stay free."],"tags":["webgl","gles","shader-compile","context-loss","panic"],"backgroundTag":"gl-resource-creation-failed","analyzedSha":"3e11ff59bf3f9795d285ecc045014089640d7248","analyzedAt":"2026-09-03T01:43:21.459Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T07:17:11.731Z"}