stride3d/stride · error · ArgumentNullException
renderCallback
Error message
renderCallback
What it means
Argument-null validation on the renderCallback parameter of WindowsMessageLoop.Run. The message loop invokes this callback every iteration to render a frame; a null callback would crash the loop on its first tick, so Run rejects it up front with ArgumentNullException named 'renderCallback'.
Solutions
- Pass a non-null RenderCallback delegate to Run
- Ensure the delegate field is assigned before Run is invoked
Example fix
// before WindowsMessageLoop.Run(form, renderCallback); // renderCallback not assigned // after renderCallback = () => RenderFrame(); WindowsMessageLoop.Run(form, renderCallback);
Defensive patterns
Strategy: validation
Validate before calling
if (renderCallback is null) throw new InvalidOperationException("renderCallback must be assigned");
WindowsMessageLoop.Run(form, renderCallback); Type guard
bool HasCallback(RenderCallback? cb) => cb is not null;
Try / catch
try { WindowsMessageLoop.Run(form, renderCallback); } catch (ArgumentNullException) { /* callback missing; log and abort */ } Prevention
- Assign the render delegate before invoking Run
- Use a lambda inline (Run(form, RenderFrame)) to avoid unset-field bugs
When it happens
Trigger: Calling Run(form, null) or passing an unset delegate field.
Common situations: Refactoring renamed/removed the render method leaving a null delegate; conditional wiring where the callback is only assigned in some code paths.
Related errors
- form
- Control is already disposed
- uiControl
- uiControl
- A Gear constraint always needs two rigidbodies to be…
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/99dc44dbc902695d.
Report an issue: GitHub.
Appendix: source
Thrown at sources/engine/Stride.Games/Desktop/WindowsMessageLoop.cs:213
/// </summary>
public static void Run(ApplicationContext context, RenderCallback renderCallback)
{
Run(context.MainForm, renderCallback);
}
/// <summary>
/// Runs the specified main loop for the specified windows form.
/// </summary>
/// <param name="form">The form.</param>
/// <param name="renderCallback">The rendering callback.</param>
/// <param name="useApplicationDoEvents">if set to <c>true</c> indicating whether the render loop should use the default <see cref="Application.DoEvents"/> instead of a custom window message loop lightweight for GC. Default is false.</param>
/// <exception cref="System.ArgumentNullException">form
/// or
/// renderCallback</exception>
public static void Run(Control form, RenderCallback renderCallback, bool useApplicationDoEvents = false)
{
if (form == null) throw new ArgumentNullException("form");
if (renderCallback == null) throw new ArgumentNullException("renderCallback");
using (var renderLoop = new WindowsMessageLoop(form) { UseApplicationDoEvents = useApplicationDoEvents })
{
while (renderLoop.NextFrame())
{
renderCallback();
}
}
}
}
}
#endif
View on GitHub (pinned to 96fad776d2)