stride3d/stride · error · InvalidOperationException
The . must not be zero.
Error message
The {nameof(WindowHandle)}.{nameof(WindowHandle.Handle)} must not be zero. What it means
CreateSwapChainForWindows creates a desktop (HWND-based) DXGI swapchain, which requires a real native window handle. If WindowHandle.Handle is IntPtr.Zero there is no window to attach the swapchain to, so Stride throws InvalidOperationException before calling CreateSwapChainForDesktop.
Solutions
- Provide a valid non-zero HWND in DeviceWindowHandle.Handle before creating the presenter.
- If you only need offscreen rendering, render to a RenderTarget/Texture instead of creating a swapchain.
- Ensure presenter creation happens after the native window exists and its handle is cached.
Example fix
// before
var description = new GraphicsPresenterDescription { DeviceWindowHandle = new WindowHandle() };
// after
var description = new GraphicsPresenterDescription { DeviceWindowHandle = new WindowHandle { Handle = form.Handle } }; Defensive patterns
Strategy: validation
Validate before calling
if (description.DeviceWindowHandle == null || description.DeviceWindowHandle.Handle == IntPtr.Zero)
throw new InvalidOperationException("A valid window handle is required to create a swapchain"); Type guard
bool HasValidHandle(WindowHandle h) => h is { Handle: not 0 }; Try / catch
try { presenter = new SwapChainGraphicsPresenter(device, desc); }
catch (InvalidOperationException ex) when (ex.Message.Contains("must not be zero"))
{ throw new ApplicationException("Initialize the window before creating the presenter", ex); } Prevention
- Create the native window before initializing the graphics presenter
- Offscreen rendering should use RenderTargets, not a swapchain
- Assert Handle != IntPtr.Zero in presenter-factory code
When it happens
Trigger: Constructing a SwapChainGraphicsPresenter on a non-UWP Direct3D platform while Description.DeviceWindowHandle.Handle == 0, or DeviceWindowHandle being effectively empty despite being non-null.
Common situations: Headless/offscreen rendering attempts on Windows (developers assume a swapchain works without a window); forgetting to pass the actual window handle from the UI framework (WinForms Control.Handle, SDL/WPF HWND) into the presenter description; ordering issues where presenter creation runs before the window is created.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- DeviceWindowHandle cannot be null
- SurfaceRotation ' ' is not supported on Direct3D presenters.
- Window context [ ] not supported while creating SwapChain
- Custom strides is not supported with packed PixelFormats
- Unexpected error on Present
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/02d2ff45f88126e7.
Report an issue: GitHub.
Appendix: source
Thrown at sources/engine/Stride.Graphics/Direct3D/SwapChainGraphicsPresenter.Direct3D.cs:692
throw new NotSupportedException($"Window context [{Description.DeviceWindowHandle.Context}] not supported while creating SwapChain");
}
this.swapChain = swapChain;
swapChainVersion = GetLatestDxgiSwapChainVersion(swapChain);
}
#else
/// <summary>
/// Creates or reinitializes the Swap-Chain on the desktop Windows platform.
/// </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 CreateSwapChainForWindows()
{
var hwndPtr = Description.DeviceWindowHandle.Handle;
if (hwndPtr == 0)
throw new InvalidOperationException($"The {nameof(WindowHandle)}.{nameof(WindowHandle.Handle)} must not be zero.");
CreateSwapChainForDesktop(hwndPtr);
}
private void CreateSwapChainForDesktop(IntPtr handle)
{
#if STRIDE_GRAPHICS_API_DIRECT3D12
useFlipModel = true;
#else
// https://devblogs.microsoft.com/directx/dxgi-flip-model/#what-do-i-have-to-do-to-use-flip-model
useFlipModel = Description.MultisampleCount == MultisampleCount.None && flipModelSupport;
#endif
var swapchainFormat = Description.BackBufferFormat;
bufferCount = 1;
if (useFlipModel)
{View on GitHub (pinned to 96fad776d2)