bevyengine/bevy · warning · ShaderCacheError

Shader import not yet available.

Error message

Shader import not yet available.

What it means

ShaderCacheError::ShaderImportNotYetAvailable is a transient condition returned by ShaderCache::get when a shader's asset-path imports have not all resolved yet (n_asset_imports != n_resolved_asset_imports), or when Wesl compilation fails with a module-not-found error (shader_cache.rs:294-306, after a one-time `warn!` "Shader `...` has an unresolved import"). PipelineCache treats it as 'waiting' and retries on later frames; it only becomes a permanent stall if the import can never resolve (e.g. wrong path).

Source

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

    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"),
        })
    }

    #[test]
    fn import_resolution() {

View on GitHub (pinned to 227d3a6c66)

Solutions

  1. Do nothing if transient — the cache retries every frame and the pipeline appears once imports load
  2. If the pipeline never appears, look for the one-time warning 'Shader `...` has an unresolved import' and fix the import path to match the imported shader's real asset path
  3. Make sure imported shader assets themselves are loaded and registered before relying on the importing shader
  4. For Wesl shaders, ensure import_path is a well-formed module path resolvable by wesl_module_path

Example fix

// before — import never resolves: file is shaders/common_lighting.wesl
imports: vec![ShaderImport::AssetPath("shaders/common.wesl".into())]

// after — path matches the imported shader's actual asset path
imports: vec![ShaderImport::AssetPath("shaders/common_lighting.wesl".into())]
Defensive patterns

Strategy: retry

Try / catch

// PipelineCache already retries; when calling ShaderCache directly:
match shader_cache.get(id, defs) {
    Err(ShaderCacheError::ShaderImportNotYetAvailable) => { /* requeue for next frame */ }
    Err(ShaderCacheError::ProcessShaderError(msg)) => { error!("{msg}"); }
    other => other?,
}

Prevention

When it happens

Trigger: Using a shader asset the same frame it is created while its ShaderImport::AssetPath dependencies are still loading; Wesl code importing a module whose backing asset is not yet registered; hot-reloading that adds a new import; a typo'd import path so resolution never succeeds.

Common situations: Spawning render objects immediately after asset_server.load() of a shader that imports other shader assets; editor/hot-reload workflows; import paths with wrong file names or missing .wesl extension; first frame after adding new shader files to the project.

Related errors


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