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

  1. Pass a valid, non-null Control/Form instance to Run
  2. Ensure the form is constructed before the render loop starts
  3. 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

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


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)