bevyengine/bevy · error
Pipeline has not been compiled yet. It is still in the 'Crea
Error message
Pipeline has not been compiled yet. It is still in the 'Creating' state.
What it means
CachedPipelineState::unwrap() panics when the pipeline is in the 'Creating' state: the creation Task<Result<Pipeline, ShaderCacheError>> is currently running but has not finished. Unlike 'Queued', the task already started (shader compilation / pipeline creation in progress); unwrap() still fails because the GPU object is not available yet.
Source
Thrown at crates/bevy_render/src/render_resource/pipeline_cache.rs:77
impl CachedPipelineState {
/// Convenience method to "unwrap" a pipeline state into its underlying GPU object.
///
/// # Returns
///
/// The method returns the allocated pipeline GPU object.
///
/// # Panics
///
/// This method panics if the pipeline GPU object is not available, either because it is
/// pending creation or because an error occurred while attempting to create GPU object.
pub fn unwrap(&self) -> &Pipeline {
match self {
CachedPipelineState::Ok(pipeline) => pipeline,
CachedPipelineState::Queued => {
panic!("Pipeline has not been compiled yet. It is still in the 'Queued' state.")
}
CachedPipelineState::Creating(..) => {
panic!("Pipeline has not been compiled yet. It is still in the 'Creating' state.")
}
CachedPipelineState::Err(err) => panic!("{}", err),
}
}
}
// The default webgpu `max_bind_groups` is 4. Most desktop GPUs support 8.
// Since the element size we used below is small, we inline 8 on the stack.
const BIND_GROUP_LAYOUTS_INLINE_CAPACITY: usize = 8;
type ImmediateSize = u32;
type LayoutCacheKey = (
SmallVec<[BindGroupLayoutId; BIND_GROUP_LAYOUTS_INLINE_CAPACITY]>,
ImmediateSize,
);
wgpu_wrapper! {
struct WgpuPipelineLayout(PipelineLayout);View on GitHub (pinned to 8d743eb7dc)
Solutions
- Match on the state and skip drawing while it is Creating/Queued: if let CachedPipelineState::Ok(pipeline) = ...
- Defer pipeline-dependent work to a system that runs every frame and checks readiness, instead of a one-shot initialization system
- In tests, call PipelineCache::block_on_render_pipeline / block_on_compute_pipeline or advance the app several update() ticks
- Keep an initialization resource/flag that flips only once the pipeline reports Ok so dependent systems gate on it
Example fix
// before
let pipeline = pipeline_cache.get_render_pipeline_state(pipeline_id).unwrap();
// after
match pipeline_cache.get_render_pipeline_state(pipeline_id) {
CachedPipelineState::Ok(pipeline) => { /* build bind groups / draw */ }
CachedPipelineState::Err(err) => { error!("pipeline failed: {err}"); }
_ => { /* still Queued/Creating: skip this frame */ }
} Defensive patterns
Strategy: type-guard
Validate before calling
use bevy::render::render_resource::CachedPipelineState;
fn pipeline_is_ready(
cache: &PipelineCache,
id: CachedRenderPipelineId,
) -> bool {
matches!(
cache.get_render_pipeline_state(id),
CachedPipelineState::Ok(_)
)
} Type guard
fn as_ready_pipeline(
cache: &PipelineCache,
id: CachedRenderPipelineId,
) -> Option<&bevy::render::render_resource::Pipeline> {
match cache.get_render_pipeline_state(id) {
CachedPipelineState::Ok(p) => Some(p),
_ => None, // Queued, Creating, or Err
}
} Prevention
- Treat 'pipeline not ready on frame N' as a normal state: skip drawing and retry next frame
- Log CachedPipelineState::Err variants so failed compiles surface instead of looking like an infinite Creating loop
- Order pipeline-consuming systems after the cache-updating systems each frame
When it happens
Trigger: Calling get_render_pipeline_state(id).unwrap() (or get_compute_pipeline_state().unwrap()) during the frames while the pipeline compile task is executing — typically one to a few frames after queueing, or on machines with slow shader compilation.
Common situations: First frames after app startup when shaders are still compiling; heavy scenes with many pipelines; CI machines or web builds where compilation is slow; code that worked locally because compilation finished fast but races on slower hardware.
Related errors
- Pipeline has not been compiled yet. It is still in the 'Queu
- Failed to catch panic!
- Cannot call `ReflectComponent::reflect_mut` on component {na
- Cannot call `ReflectComponent::reflect_unchecked_mut` on com
- component should represent a type.
AI-assisted analysis of bevyengine/bevy@8d743eb7dc (2026-08-20).
Data as JSON: /api/errors/a9207c44e4fd86f1.
Report an issue: GitHub.