{"record":{"id":"d1451cca88a33e16","repo":"bevyengine/bevy","slug":"no-safety-checks-are-performed-for-spirv-shaders","errorCode":null,"errorMessage":"no safety checks are performed for spirv shaders. use `create_shader_module` instead","messagePattern":"no safety checks are performed for spirv shaders\\. use `create_shader_module` instead","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/bevy_render/src/renderer/render_device.rs","lineNumber":106,"sourceCode":"        #[cfg(not(feature = \"spirv_shader_passthrough\"))]\n        // SAFETY: the caller is responsible for upholding the safety requirements\n        unsafe {\n            self.device\n                .create_shader_module_trusted(desc, wgpu::ShaderRuntimeChecks::unchecked())\n        }\n    }\n\n    /// Creates and validates a [`ShaderModule`](wgpu::ShaderModule) from either SPIR-V or WGSL source code.\n    ///\n    /// See [`ValidateShader`](bevy_shader::ValidateShader) for more information on the tradeoffs involved with shader validation.\n    #[inline]\n    pub fn create_and_validate_shader_module(\n        &self,\n        desc: wgpu::ShaderModuleDescriptor,\n    ) -> wgpu::ShaderModule {\n        #[cfg(feature = \"spirv_shader_passthrough\")]\n        match &desc.source {\n            wgpu::ShaderSource::SpirV(_source) => panic!(\"no safety checks are performed for spirv shaders. use `create_shader_module` instead\"),\n            _ => self.device.create_shader_module(desc),\n        }\n        #[cfg(not(feature = \"spirv_shader_passthrough\"))]\n        self.device.create_shader_module(desc)\n    }\n\n    /// Check for resource cleanups and mapping callbacks.\n    ///\n    /// Return `true` if the queue is empty, or `false` if there are more queue\n    /// submissions still in flight. (Note that, unless access to the [`wgpu::Queue`] is\n    /// coordinated somehow, this information could be out of date by the time\n    /// the caller receives it. `Queue`s can be shared between threads, so\n    /// other threads could submit new work at any time.)\n    ///\n    /// no-op on the web, device is automatically polled.\n    #[inline]\n    pub fn poll(&self, maintain: wgpu::PollType) -> Result<PollStatus, PollError> {\n        self.device.poll(maintain)","sourceCodeStart":88,"sourceCodeEnd":124,"githubUrl":"https://github.com/bevyengine/bevy/blob/396ca727080776bd313bb892423b7d94e03b81b4/crates/bevy_render/src/renderer/render_device.rs#L88-L124","documentation":"RenderDevice::create_and_validate_shader_module is the validating wrapper around wgpu shader-module creation. When the 'spirv_shader_passthrough' feature is enabled and the descriptor's source is ShaderSource::SpirV, it deliberately panics: the validation path cannot check SPIR-V, so callers must use the passthrough method create_shader_module instead (which trusts the SPIR-V — hence the feature's name and the message's warning that no safety checks are performed).","triggerScenarios":"Calling render_device.create_and_validate_shader_module(wgpu::ShaderModuleDescriptor { source: ShaderSource::SpirV(bytes), .. }) while the spirv_shader_passthrough cargo feature is enabled in the project.","commonSituations":"Integrating precompiled SPIR-V pipelines with the passthrough feature turned on but routing the descriptor through the safe/validating helper; refactoring call sites from create_shader_module to the validating variant without branching on the source type.","solutions":["Call render_device.create_shader_module(desc) for SPIR-V sources (the passthrough path you opted into with the feature)","Branch on the source: validate WGSL, pass through SPIR-V","Convert the shader to WGSL and keep using the validating API everywhere"],"exampleFix":"// before\nlet module = render_device.create_and_validate_shader_module(desc); // panics on SpirV\n\n// after\nlet module = match desc.source {\n    wgpu::ShaderSource::SpirV(_) => render_device.create_shader_module(desc),\n    _ => render_device.create_and_validate_shader_module(desc),\n};","handlingStrategy":"validation","validationCode":"// Route by source type before creating the module:\nfn create_module(\n    device: &RenderDevice,\n    desc: wgpu::ShaderModuleDescriptor,\n) -> wgpu::ShaderModule {\n    match &desc.source {\n        wgpu::ShaderSource::SpirV(_) => device.create_shader_module(desc),\n        _ => device.create_and_validate_shader_module(desc),\n    }\n}","typeGuard":"fn is_spirv(desc: &wgpu::ShaderModuleDescriptor) -> bool {\n    matches!(desc.source, wgpu::ShaderSource::SpirV(_))\n}","tryCatchPattern":null,"preventionTips":["Only enable the spirv_shader_passthrough feature when you actually pass SPIR-V through unchecked","Never route ShaderSource::SpirV into create_and_validate_shader_module","Prefer WGSL so every module goes through validation"],"tags":["bevy","spirv","shader-module","validation","panic"],"backgroundTag":"unsupported-shader-format","analyzedSha":"396ca727080776bd313bb892423b7d94e03b81b4","analyzedAt":"2026-08-20T16:12:39.808Z","contentChangedAt":"2026-08-20T16:12:39.808Z","schemaVersion":2},"datasetVersion":"2026-09-09T01:17:15.007Z"}