stride3d/stride · error · ArgumentNullException
form
Error message
form
What it means
Argument-null validation on the form parameter of WindowsMessageLoop.Run(ApplicationContext, RenderCallback). The run delegates to Run(context.MainForm, renderCallback), and the overload it forwards to throws ArgumentNullException named 'form' when the form is null — i.e. when the ApplicationContext has no main form — because the message loop needs a window to pump messages for.
Solutions
- Pass a valid, non-null Control/Form instance to Run
- Ensure the form is constructed before the render loop starts
- Guard construction failures so a null form is never propagated
Example fix
// before
WindowsMessageLoop.Run(form, Render); // form null
// after
var form = new RenderForm("App");
WindowsMessageLoop.Run(form, Render); Defensive patterns
Strategy: validation
Validate before calling
if (form is null) throw new InvalidOperationException("form must be created before WindowsMessageLoop.Run");
WindowsMessageLoop.Run(form, callback); Type guard
bool HasForm(Control? c) => c is not null;
Try / catch
try { WindowsMessageLoop.Run(form, callback); } catch (ArgumentNullException) { /* form was null; log and abort startup */ } Prevention
- Construct the form before starting the render loop
- Never pass nullable form fields without null checks
When it happens
Trigger: Calling Run(null, renderCallback) with a null form.
Common situations: Form creation failed earlier and returned null; refactoring moved form construction after Run; passing an uninitialized field.
Related errors
- renderCallback
- 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/369dbd0fb6b9a56b.
Report an issue: GitHub.
Appendix: source
Thrown at sources/engine/Stride.Games/Desktop/WindowsMessageLoop.cs:212
/// Runs the specified main loop in the specified context.
/// </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)