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

  1. Enable the feature in Cargo.toml: `bevy = { version = "...", features = ["shader_format_spirv"] }`
  2. If you control the shader, port it to WGSL (`Shader::from_wgsl`) and drop the SPIR-V dependency entirely
  3. If a dependency pulls in SPIR-V shaders, check that crate's docs for a feature that enables `shader_format_spirv` transitively
  4. 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

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.