stride3d/stride · error · InvalidOperationException
DeviceWindowHandle cannot be null
Error message
DeviceWindowHandle cannot be null
What it means
SwapChainGraphicsPresenter.CreateSwapChain throws InvalidOperationException when PresentationParameters.DeviceWindowHandle is null, since a D3D swap chain must be created against a valid output window. The XML docs on the method explicitly state the handle must be non-null and its Handle non-zero. This fires in the constructor and in OnRecreated (swap-chain re-creation).
Solutions
- Set PresentationParameters.DeviceWindowHandle to a valid window (e.g. gameWindow.NativeWindow? or WindowHandle from your platform window) before creating the presenter/device
- For offscreen rendering, use the appropriate offscreen/graphics-context presenter instead of a swap chain presenter
- Guard window lifetime: don't trigger OnRecreated/device reinit after the window is disposed
- Verify the handle's Handle value is non-zero before init
Example fix
// before
var parameters = new PresentationParameters(); // DeviceWindowHandle is null
var device = GraphicsDevice.New(null, parameters);
// after
var parameters = new PresentationParameters
{
DeviceWindowHandle = Game.Window.NativeWindow // must be a valid, live window handle
};
var device = GraphicsDevice.New(null, parameters); Defensive patterns
Strategy: validation
Validate before calling
if (parameters.DeviceWindowHandle is null || parameters.DeviceWindowHandle.Handle == IntPtr.Zero)
throw new InvalidOperationException("Assign a valid DeviceWindowHandle before creating a D3D presenter."); Type guard
bool HasValidWindowHandle(PresentationParameters p) =>
p?.DeviceWindowHandle != null && p.DeviceWindowHandle.Handle != IntPtr.Zero; Try / catch
try { new SwapChainGraphicsPresenter(device, parameters); }
catch (InvalidOperationException ex) when (ex.Message.Contains("DeviceWindowHandle"))
{
// fall back to offscreen presenter or re-init with a real window handle
} Prevention
- Always set DeviceWindowHandle before GraphicsDevice/presenter creation
- Use offscreen renderers for headless scenarios instead of nulling the handle
- Track window lifetime and stop presenting/recreating after disposal
- Assert handle.Handle != IntPtr.Zero in app startup
When it happens
Trigger: Constructing SwapChainGraphicsPresenter (directly or via GraphicsDevice/presenter factory on Direct3D) with PresentationParameters whose DeviceWindowHandle was never set, or calling OnRecreated after the window was closed/disposed leaving the handle null.
Common situations: Running a Stride headless/offscreen setup on a D3D backend without assigning a window handle or using the proper offscreen presenter; forgetting to set GameWindow/window handle before graphics device init; window closed then device recreate triggered; copy-pasting presenter setup from non-windowed contexts.
Related errors
- The . must not be zero.
- Unexpected error on Present
- SurfaceRotation ' ' is not supported on Direct3D presenters.
- Window context [ ] not supported while creating SwapChain
- Format ' ' is not supported when using a flip model…
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/170b51065cc09b57.
Report an issue: GitHub.
Appendix: source
Thrown at sources/engine/Stride.Graphics/Direct3D/SwapChainGraphicsPresenter.Direct3D.cs:556
DepthStencilBuffer.InitializeFrom(newTextureDescription);
foreach (var childTexture in childrenTextures)
{
childTexture.InitializeFrom(parentTexture: DepthStencilBuffer, in childTexture.ViewDescription);
}
}
/// <summary>
/// Creates or reinitializes the Swap-Chain with the current configuration.
/// </summary>
/// <exception cref="InvalidOperationException">
/// <see cref="PresentationParameters.DeviceWindowHandle"/> is <see langword="null"/> or
/// the <see cref="WindowHandle.Handle"/> is invalid or zero.
/// </exception>
private void CreateSwapChain()
{
if (Description.DeviceWindowHandle is null)
throw new InvalidOperationException("DeviceWindowHandle cannot be null");
// D3D presenters don't honor SurfaceRotation (DXGI handles rotation transparently).
if (SurfaceRotation != SurfaceRotation.Identity)
throw new NotImplementedException($"SurfaceRotation '{SurfaceRotation}' is not supported on Direct3D presenters.");
#if STRIDE_PLATFORM_UWP
CreateSwapChainForUWP();
#else
CreateSwapChainForWindows();
#endif
}
#if STRIDE_PLATFORM_UWP
/// <summary>
/// Creates or reinitializes the Swap-Chain on the Universal Windows Platform (UWP).
/// </summary>
private void CreateSwapChainForUWP()
{View on GitHub (pinned to 96fad776d2)