stride3d/stride · error · InvalidOperationException
Unexpected null GraphicsDevice
Error message
Unexpected null GraphicsDevice
What it means
After GraphicsDeviceManager attempts to create the device (CreateDevice), it validates that the GraphicsDevice property is non-null before reading presentation parameters; a null here means device creation silently failed to assign the device, violating an internal invariant. This is a defensive check surfaced when CreateDevice or the factory path did not actually produce a device.
Solutions
- Inspect earlier logs/inner exceptions: fix the underlying CreateDevice/IGraphicsDeviceFactory failure so it actually produces a GraphicsDevice.
- Ensure a stock factory (e.g. DeviceFactorySDL / platform default) is registered rather than a custom stub that returns without creating a device.
- Update Stride — this null state can result from platform bugs fixed in later versions.
Example fix
// before public class MyFactory : IGraphicsDeviceFactory // never assigns GraphicsDevice // after // use the platform factory: game.Services.AddService<IGraphicsDeviceFactory>(new DeviceFactorySDL());
Defensive patterns
Strategy: try-catch
Validate before calling
if (game.Services.GetService<IGraphicsDeviceFactory>() is not DeviceFactorySDL && customFactory is null)
throw new InvalidOperationException("Register a real IGraphicsDeviceFactory"); Type guard
bool DeviceCreated(GameBase g) => g.GraphicsDevice != null;
Try / catch
try { gdm.ApplyChanges(); }
catch (InvalidOperationException ex) when (ex.Message.Contains("Unexpected null GraphicsDevice"))
{
logger.LogError(ex, "Device creation did not produce a GraphicsDevice");
throw;
} Prevention
- Use stock platform factories instead of custom stubs.
- Check CreateDevice inner exceptions/logs rather than swallowing them.
- Keep Stride updated for platform device-creation fixes.
When it happens
Trigger: Code path in GraphicsDeviceManager (e.g. changing device/fullscreen toggling) sets needToCreateNewDevice and calls CreateDevice, yet GraphicsDevice remains null afterwards — e.g. CreateDevice's factory returned without constructing the device, or a prior creation failure was swallowed.
Common situations: Custom IGraphicsDeviceFactory implementations that don't set the device, partially failed device creation with earlier exceptions caught upstream, race conditions during window creation/ recreation, or platform factory mismatches.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- A overlaps with another element. Check the element's offset
- A region can only be specified for Textures with…
- adapter
- AlphaLoadMode. not supported for the Stride image format…
- ArgumentNullException
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/73d27f4ac44ec17b.
Report an issue: GitHub.
Appendix: source
Thrown at sources/engine/Stride.Games/GraphicsDeviceManager.cs:1243
GraphicsDevice.Presenter.Resize(newWidth, newHeight, newFormat);
// Change full screen if needed
GraphicsDevice.Presenter.IsFullScreen = graphicsDeviceInformation.PresentationParameters.IsFullScreen;
needToCreateNewDevice = false;
}
catch { /* Ignore any exception */ }
}
}
// If we still need to create a device, then we need to create it
if (needToCreateNewDevice)
{
CreateDevice(graphicsDeviceInformation);
}
if (GraphicsDevice is null)
throw new InvalidOperationException("Unexpected null GraphicsDevice");
var presentationParameters = GraphicsDevice.Presenter.Description;
isReallyFullScreen = presentationParameters.IsFullScreen;
if (presentationParameters.BackBufferWidth != 0)
width = presentationParameters.BackBufferWidth;
if (presentationParameters.BackBufferHeight != 0)
height = presentationParameters.BackBufferHeight;
deviceSettingsChanged = false;
}
finally
{
// Notify the game Window that the screen device change is over
if (isBeginScreenDeviceChange)
{
game.Window.EndScreenDeviceChange(width, height);
game.Window.SetIsReallyFullscreen(isReallyFullScreen);
}View on GitHub (pinned to 96fad776d2)