bevyengine/bevy · critical
DrawFunctions<{}> must be added to the world as a resource b
Error message
DrawFunctions<{}> must be added to the world as a resource before adding render commands to it What it means
SubApp::add_render_command (draw.rs:372) panics when the DrawFunctions<P> resource has not been added to that world yet. Render commands for phase item type P are stored inside the DrawFunctions<P> resource, so the resource must be initialized before any command is added. The panic names P so you know which phase's resource is missing.
Source
Thrown at crates/bevy_render/src/render_phase/draw.rs:372
&mut self,
) -> &mut Self
where
C::Param: ReadOnlySystemParam;
}
impl AddRenderCommand for SubApp {
fn add_render_command<P: PhaseItem, C: RenderCommand<P> + Send + Sync + 'static>(
&mut self,
) -> &mut Self
where
C::Param: ReadOnlySystemParam,
{
let draw_function = RenderCommandState::<P, C>::new(self.world_mut());
let draw_functions = self
.world()
.get_resource::<DrawFunctions<P>>()
.unwrap_or_else(|| {
panic!(
"DrawFunctions<{}> must be added to the world as a resource \
before adding render commands to it",
core::any::type_name::<P>(),
);
});
draw_functions.write().add_with::<C, _>(draw_function);
self
}
}
impl AddRenderCommand for App {
fn add_render_command<P: PhaseItem, C: RenderCommand<P> + Send + Sync + 'static>(
&mut self,
) -> &mut Self
where
C::Param: ReadOnlySystemParam,
{
SubApp::add_render_command::<P, C>(self.main_mut());View on GitHub (pinned to 396ca72708)
Solutions
- Init the resource first: render_app.init_resource::<DrawFunctions<P>>() in your plugin build, then call add_render_command.
- Make sure you are operating on the render sub-app (app.get_sub_app_mut(RenderApp) / RenderApp), not the main world.
- For built-in phases, ensure the corresponding core plugin (which inits DrawFunctions) is added before your plugin (add a plugin dependency).
Example fix
// before: added on the main app world, resource not present
app.add_render_command::<Opaque3d, DrawCustom>();
// after: go through the render sub-app and init the resource for custom phases
if let Some(render_app) = app.get_sub_app_mut(RenderApp) {
render_app
.init_resource::<DrawFunctions<CustomPhaseItem>>() // for custom phases
.add_render_command::<CustomPhaseItem, DrawCustom>();
} Defensive patterns
Strategy: validation
Validate before calling
if let Some(render_app) = app.get_sub_app_mut(RenderApp) {
if !render_app.world().contains_resource::<DrawFunctions<CustomPhaseItem>>() {
render_app.init_resource::<DrawFunctions<CustomPhaseItem>>();
}
render_app.add_render_command::<CustomPhaseItem, DrawCustom>();
} Prevention
- Always add render commands through the render sub-app (get_sub_app_mut(RenderApp)).
- For custom phases, init_resource::<DrawFunctions<P>>() in the same plugin that registers commands.
- For built-in phases, depend on the plugin that initializes their DrawFunctions.
When it happens
Trigger: Calling add_render_command on an app/world where init_resource::<DrawFunctions<P>>() has not run - most commonly calling it on the main app world instead of the Render sub-app, or a custom phase plugin that forgets to init the resource before registering commands.
Common situations: Custom render phases: forgetting render_app.init_resource::<DrawFunctions<MyPhaseItem>>() in the plugin; adding render commands in Plugin::build without going through app.get_sub_app_mut(RenderApp); using a built-in phase (e.g. Opaque3d) before the plugin that initializes its DrawFunctions is added; Bevy version migrations that moved where the resource is initialized.
Related errors
- ParamSet parameter validation failed: {err}
- resource does not exist: {}
- Resource `{}` was inserted during a call to World::resource_
- The TimeSender channel should always be empty during render.
- Cannot call `ReflectComponent::reflect_mut` on component {na
AI-assisted analysis of bevyengine/bevy@396ca72708 (2026-08-20).
Data as JSON: /api/errors/cfdc2090e860c285.
Report an issue: GitHub.