bevyengine/bevy · error

Error calling hotpatched system. Run a full rebuild

Error message

Error calling hotpatched system. Run a full rebuild

What it means

With the hotpatching feature, exclusive function systems execute through subsecond jump-table function pointers instead of direct calls. try_call_with_ptr fails when the stored current_ptr no longer refers to the current jump table - typically because a hot patch was applied but this system's pointer was not refreshed via refresh_hotpatch. The expect then panics with this message; the remedy is a full rebuild.

Source

Thrown at crates/bevy_ecs/src/system/exclusive_function_system.rs:131

        world.last_change_tick_scope(self.system_meta.last_run, |world| {
            #[cfg(feature = "trace")]
            let _span_guard = self.system_meta.system_span.enter();

            let params = F::Param::get_param(
                self.param_state.as_mut().expect(PARAM_MESSAGE),
                &self.system_meta,
            )?;

            #[cfg(feature = "hotpatching")]
            let out = {
                let mut hot_fn =
                    subsecond::HotFn::current(<F as ExclusiveSystemParamFunction<Marker>>::run);
                // SAFETY:
                // - pointer used to call is from the current jump table
                unsafe {
                    hot_fn
                        .try_call_with_ptr(self.current_ptr, (&mut self.func, world, input, params))
                        .expect("Error calling hotpatched system. Run a full rebuild")
                }
            };
            #[cfg(not(feature = "hotpatching"))]
            let out = self.func.run(world, input, params);

            world.flush();
            self.system_meta.last_run = world.increment_change_tick();

            IntoResult::into_result(out)
        })
    }

    #[cfg(feature = "hotpatching")]
    #[inline]
    fn refresh_hotpatch(&mut self) {
        let new = subsecond::HotFn::current(<F as ExclusiveSystemParamFunction<Marker>>::run)
            .ptr_address();
        if new != self.current_ptr {

View on GitHub (pinned to 396ca72708)

Solutions

  1. Do a full rebuild and restart of the application as the message says - the jump table and all pointers are then recreated consistently.
  2. Ensure the system participates in the normal refresh path: systems inside schedules get refresh_hotpatch on reload; if you cache one outside a schedule, call refresh_hotpatch on it after each patch.
  3. If it recurs for systems that do live in schedules, report it - the refresh propagation missed that system.
Defensive patterns

Strategy: fallback

Prevention

When it happens

Trigger: A subsecond hot patch landed while the app was running or paused and the system's cached pointer went stale because refresh_hotpatch was not propagated to it; resuming execution after a partially applied patch.

Common situations: Iterating with hotpatching enabled and patching while paused at a breakpoint; systems held outside schedules (cached in resources) that never receive the refresh; reload-sequencing bugs in the hot-reload tooling.

Related errors


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