bevyengine/bevy · critical

spirv not yet implemented

Error message

spirv not yet implemented

What it means

Panic in Shader::Source::as_str(). A Shader's source can be Wgsl, Wesl, or SpirV bytes; as_str() only has meaning for the textual variants and explicitly panics with 'spirv not yet implemented' for SpirV because there is no way to return the binary payload as a string.

Source

Thrown at crates/bevy_shader/src/shader.rs:237

/// Raw shader source code.
#[expect(missing_docs, reason = "The variants are self-explanatory.")]
#[derive(Debug, Clone)]
pub enum Source {
    Wgsl(Cow<'static, str>),
    Wesl(Cow<'static, str>),
    SpirV(Cow<'static, [u8]>),
    // TODO: consider the following
    // PrecompiledSpirVMacros(HashMap<HashSet<String>, Vec<u32>>)
    // NagaModule(Module) ... Module impls Serialize/Deserialize
}

impl Source {
    /// The underlying source code string, unless it is SPIR-V.
    pub fn as_str(&self) -> &str {
        match self {
            Source::Wgsl(s) | Source::Wesl(s) => s,
            Source::SpirV(_) => panic!("spirv not yet implemented"),
        }
    }
}

/// The [`AssetLoader`] responsible for loading unprocessed shader assets.
#[derive(Default, TypePath)]
pub struct ShaderLoader;

/// An error encountered while loading a shader's source.
#[non_exhaustive]
#[derive(Debug, Error)]
#[expect(missing_docs, reason = "The variants are self-explanatory.")]
pub enum ShaderLoaderError {
    #[error("Could not load shader: {0}")]
    Io(#[from] std::io::Error),
    #[error("Could not parse shader: {0}")]
    Parse(#[from] alloc::string::FromUtf8Error),
}

View on GitHub (pinned to 396ca72708)

Solutions

  1. Match on the Source variant before treating it as text instead of calling as_str()
  2. Provide the shader as .wgsl/.wesl text if your pipeline needs source access
  3. Gate SPIR-V shaders out of text-based preprocessing paths

Example fix

// before
let src = shader.get_source().as_str(); // panics for SpirV

// after
match shader.get_source() {
    Source::Wgsl(s) | Source::Wesl(s) => process_text(s),
    Source::SpirV(bytes) => process_binary(bytes),
}
Defensive patterns

Strategy: type-guard

Type guard

fn is_text_shader(shader: &Shader) -> bool {
    matches!(
        shader.get_source(),
        Source::Wgsl(_) | Source::Wesl(_)
    )
}

Prevention

When it happens

Trigger: Calling shader.get_source().as_str() (or any code path that assumes text) on a shader created via Shader::from_spirv / loaded from a .spv file. The match arm for Source::SpirV panics.

Common situations: Shader processing pipelines (reflection, preprocessing, import resolution) written against textual shaders and then fed a SPIR-V asset; tools that log or inspect shader source without checking the variant.

Related errors


AI-assisted analysis of bevyengine/bevy@396ca72708 (2026-08-20). Data as JSON: /api/errors/478b988b32952bd6. Report an issue: GitHub.