stride3d/stride · error · Exception
AfterUpdate cannot be called out of the micro-thread…
Error message
AfterUpdate cannot be called out of the micro-thread context.
What it means
AfterUpdate() yields the current micro-thread until just after the next physics tick, mirroring NextUpdate(). It only works when the caller is on a Stride micro-thread with a SynchronizationContext, since TickAwaiter resumes through those; otherwise it throws immediately.
Solutions
- Invoke AfterUpdate() from an async Stride script running on a micro-thread.
- Use engine callbacks/events (e.g. after-tick hooks) for code outside the micro-thread context.
- Restructure the logic so the post-tick continuation lives inside the script's async flow.
Example fix
// before
await Task.Run(() => sim.AfterUpdate());
// after
public async Task MyScript() {
var awaiter = sim.AfterUpdate(); // valid: on micro-thread
} Defensive patterns
Strategy: validation
Validate before calling
if (Scheduler.CurrentMicroThread is null || SynchronizationContext.Current is null) {
return; // cannot await AfterUpdate here
}
var awaiter = sim.AfterUpdate(); Try / catch
try { var a = sim.AfterUpdate(); } catch (Exception ex) { log.Warn("AfterUpdate requires micro-thread context", ex); } Prevention
- Keep post-tick continuation logic inside Stride scripts
- Avoid calling physics await APIs from unit tests or plain Tasks
- Document that AfterUpdate/NextUpdate are micro-thread-only
When it happens
Trigger: Calling BepuSimulation.AfterUpdate() from a raw Task, thread pool thread, unit test, or any code where Scheduler.CurrentMicroThread or SynchronizationContext.Current is null.
Common situations: Attempting post-physics-step synchronization from background workers or non-Stride test harnesses instead of from within Stride's script/micro-thread scheduling.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- NextUpdate cannot be called out of the micro-thread context.
- A Gear constraint always needs two rigidbodies to be…
- A Gear constraint requires two rigidbodies.
- All should have hashsets associated to them
- ArgumentNullException: data
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/83648a04d2c6a63d.
Report an issue: GitHub.
Appendix: source
Thrown at sources/engine/Stride.BepuPhysics/Stride.BepuPhysics/BepuSimulation.cs:378
/// <summary>
/// Yields execution until right before the next physics tick
/// </summary>
/// <returns>Task that will resume next tick.</returns>
public TickAwaiter NextUpdate()
{
if (Scheduler.CurrentMicroThread is null || SynchronizationContext.Current is null)
throw new Exception($"{nameof(NextUpdate)} cannot be called out of the micro-thread context.");
return new TickAwaiter(_preTickRunner, Scheduler.CurrentMicroThread, SynchronizationContext.Current);
}
/// <summary>
/// Yields execution until right after the next physics tick
/// </summary>
/// <returns>Task that will resume next tick.</returns>
public TickAwaiter AfterUpdate()
{
if (Scheduler.CurrentMicroThread is null || SynchronizationContext.Current is null)
throw new Exception($"{nameof(AfterUpdate)} cannot be called out of the micro-thread context.");
return new TickAwaiter(_postTickRunner, Scheduler.CurrentMicroThread, SynchronizationContext.Current);
}
/// <summary>
/// Whether a physics test with <paramref name="mask"/> against <paramref name="collidable"/> should be performed or entirely ignored
/// </summary>
/// <returns>True when it should be performed, false when it should be ignored</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool ShouldPerformPhysicsTest(CollisionMask mask, CollidableReference collidable)
{
var component = GetComponent(collidable);
return mask.IsSet(component.CollisionLayer);
}
/// <summary>
/// Finds the closest intersection between this ray and shapes in the simulation.
/// </summary>
/// <param name="origin">The start position for this ray</param>View on GitHub (pinned to 96fad776d2)