bevyengine/bevy · critical
Enable feature "shader_format_spirv" to use SPIR-V shaders
Error message
Enable feature "shader_format_spirv" to use SPIR-V shaders
What it means
bevy_render's PipelineCache can only turn SPIR-V bytes into a wgpu ShaderModule when the `shader_format_spirv` cargo feature is enabled. When a Shader's source is `ShaderCacheSource::SpirV` and the feature is off, `load_module` calls `unimplemented!()` and panics with this message. wgpu gates `wgpu::util::make_spirv` behind the feature, so Bevy forwards the gate to the user.
Source
Thrown at crates/bevy_render/src/render_resource/pipeline_cache.rs:135
..default()
},
)))
})
.clone()
}
}
fn load_module(
render_device: &RenderDevice,
shader_source: ShaderCacheSource,
validate_shader: &ValidateShader,
) -> Result<WgpuWrapper<ShaderModule>, ShaderCacheError> {
let shader_source = match shader_source {
#[cfg(feature = "shader_format_spirv")]
ShaderCacheSource::SpirV(data) => wgpu::util::make_spirv(data),
#[cfg(not(feature = "shader_format_spirv"))]
ShaderCacheSource::SpirV(_) => {
unimplemented!("Enable feature \"shader_format_spirv\" to use SPIR-V shaders")
}
ShaderCacheSource::Wgsl(src) => ShaderSource::Wgsl(Cow::Owned(src)),
};
let module_descriptor = ShaderModuleDescriptor {
label: None,
source: shader_source,
};
let scope = render_device
.wgpu_device()
.push_error_scope(wgpu::ErrorFilter::Validation);
let shader_module = WgpuWrapper::new(match validate_shader {
ValidateShader::Enabled => {
render_device.create_and_validate_shader_module(module_descriptor)
}
// SAFETY: we are interfacing with shader code, which may contain undefined behavior,
// such as indexing out of bounds.View on GitHub (pinned to 78002f65fa)
Solutions
- Enable the feature in Cargo.toml: `bevy = { version = "...", features = ["shader_format_spirv"] }`
- If you control the shader, port it to WGSL (`Shader::from_wgsl`) and drop the SPIR-V dependency entirely
- If a dependency pulls in SPIR-V shaders, check that crate's docs for a feature that enables `shader_format_spirv` transitively
- Run `cargo tree -e features -i bevy_render | grep spirv` to confirm whether the feature is actually active in your build
Example fix
# before
[dependencies]
bevy = "0.17" # SPIR-V sources panic: unimplemented!()
# after
[dependencies]
bevy = { version = "0.17", features = ["shader_format_spirv"] }
# or, prefer WGSL in code:
// let shader = Shader::from_spirv(spirv_bytes); // before
let shader = Shader::from_wgsl(WGSL_SOURCE); // after Defensive patterns
Strategy: validation
Validate before calling
# Cargo.toml — proxy feature so your code can gate on it
[features]
spirv_shaders = ["bevy/shader_format_spirv"]
// code that loads SPIR-V:
#[cfg(not(feature = "spirv_shaders"))]
compile_error!("SPIR-V shaders require enabling the `spirv_shaders` feature (bevy/shader_format_spirv)"); Prevention
- Prefer WGSL for all new shaders; SPIR-V support is a legacy/on-ramp path in Bevy
- If any dependency ships SPIR-V, enable bevy's `shader_format_spirv` feature once in the root Cargo.toml
- Verify with `cargo tree -e features -i bevy_render | grep spirv` before shipping
When it happens
Trigger: Loading a shader built from SPIR-V bytes (e.g. `Shader::from_spirv(...)`, a `.spv` asset, or a third-party crate that constructs SpirV shader sources) in a project where bevy_render was compiled without the `shader_format_spirv` feature. The panic occurs on first pipeline compilation for that shader.
Common situations: Using default Bevy features (SPIR-V is NOT in bevy's default feature set) while depending on a crate that ships SPIR-V shaders; trimming features with `default-features = false` and forgetting this one; migrating SPIR-V shaders from an older engine/workflow into a WGsl-first Bevy project.
Related errors
AI-assisted analysis of bevyengine/bevy@78002f65fa (2026-08-16).
Data as JSON: /api/errors/831aa099e69b7398.
Report an issue: GitHub.