bevyengine/bevy · error · ShaderCacheError

Failed to process shader: {0}

Error message

Failed to process shader:
{0}

What it means

ShaderCacheError::ProcessShaderError is returned by ShaderCache::get when the Wesl compiler (wesl::compile_sourcemap) fails to process a shader whose source is Source::Wesl. The wrapped string is the raw Wesl compiler error. It is also returned directly when a Wesl shader's import_path cannot be parsed into a module path ("Wesl shader `...` has a malformed import path"). PipelineCache logs the error and marks the pipeline as errored; the app keeps running but that pipeline never renders.

Source

Thrown at crates/bevy_shader/src/shader_cache.rs:542

    }

    fn display_name(&self, module_path: &wesl::syntax::ModulePath) -> Option<String> {
        let module_path = self.canonical_path(module_path);
        let asset_id = self.module_path_to_asset_id.get(&module_path)?;
        let shader = self.shaders.get(asset_id)?;
        Some(shader.path.clone())
    }
}

/// Type of error returned by a `PipelineCache` when the creation of a GPU pipeline object failed.
#[expect(missing_docs, reason = "Enum variants are self-explanatory")]
#[derive(Error, Debug)]
pub enum ShaderCacheError {
    #[error(
        "Pipeline could not be compiled because the following shader could not be loaded: {0:?}"
    )]
    ShaderNotLoaded(AssetId<Shader>),
    #[error("Failed to process shader:\n{0}")]
    ProcessShaderError(String),
    #[error("Shader import not yet available.")]
    ShaderImportNotYetAvailable,
    #[error("Could not create shader module: {0}")]
    CreateShaderModule(String),
}

#[cfg(test)]
mod tests {
    use super::*;

    fn test_cache() -> ShaderCache<String, ()> {
        ShaderCache::new((), |_, source, _| match source {
            ShaderCacheSource::Wgsl(wgsl) => Ok(wgsl),
            _ => panic!("expected wgsl output"),
        })
    }

View on GitHub (pinned to 227d3a6c66)

Solutions

  1. Read the embedded compiler message first — it names the file, line, and construct the Wesl compiler rejected
  2. Fix the reported syntax error or malformed import path in the .wesl source
  3. Remove `const` declarations that duplicate integer/uint shader defs; they are injected automatically from ShaderDefVal::Int/UInt
  4. Verify every import path matches the actual asset path of the imported shader
  5. If hot-reload state looks stale, restart the app to force a full shader recompile

Example fix

// before — ProcessShaderError: name 'PIXEL_RATIO' is already defined
// (the integer shader def already injects `const PIXEL_RATIO = 2;`)
const PIXEL_RATIO = 2u;
fn fs(in: VertexOutput) -> vec4<f32> {
    let s = in.pos.x * f32(PIXEL_RATIO);
    return vec4<f32>(s, 0.0, 0.0, 1.0);
}

// after — rely on the injected constant, do not redeclare it
fn fs(in: VertexOutput) -> vec4<f32> {
    let s = in.pos.x * f32(PIXEL_RATIO);
    return vec4<f32>(s, 0.0, 0.0, 1.0);
}
Defensive patterns

Strategy: try-catch

Try / catch

match shader_cache.get(pipeline_id, shader_id, &shader_defs) {
    Ok(module) => { /* use module */ }
    Err(ShaderCacheError::ProcessShaderError(msg)) => {
        error!("shader compile failed, skipping pipeline: {msg}");
        // fall back to a known-good pipeline or mark the object unrenderable
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling ShaderCache::get (directly or via PipelineCache pipeline creation) on a Wesl shader that fails wesl::compile_sourcemap with a non-module-not-found error: WGSL/Wesl syntax errors, duplicate declarations, or a const in the shader colliding with an integer shader def (the cache auto-injects `const name = value;` for every ShaderDefVal::Int/UInt def, see shader_cache.rs:277-280), or a Wesl asset whose import_path wesl_module_path() cannot parse.

Common situations: Typos introduced while hot-reloading .wesl shader files; declaring constants in shader code that are also passed as integer shader_defs; migrating shaders from naga-oil `#import` preprocessing to Wesl import syntax across Bevy upgrades; passing shader defs whose names clash with Wesl reserved words.

Related errors


AI-assisted analysis of bevyengine/bevy@227d3a6c66 (2026-08-20). Data as JSON: /api/errors/f1217ecac93e022e. Report an issue: GitHub.