stride3d/stride · error · ArgumentException
DeviceWindowHandle cannot be null
Error message
DeviceWindowHandle cannot be null
What it means
CreateSurface needs a target window handle to create the platform VkSurfaceKHR; if SwapChainGraphicsPresenter's Description.DeviceWindowHandle is null it throws ArgumentException. Without a window there is nothing to present to, and the non-headless code path cannot proceed.
Solutions
- Set Description.DeviceWindowHandle to a valid window (e.g. game.Window.NativeWindow or new WindowHandle(context, windowPtr)) before creating the presenter.
- Ensure the game window is created before graphics device/presenter initialization.
- For offscreen rendering, use the headless path instead of a swapchain presenter.
Example fix
// before
var presenter = new SwapChainGraphicsPresenter(device, new SwapChainDescription { ... });
// after
var desc = new SwapChainDescription { ... };
desc.DeviceWindowHandle = game.Window.Handle;
var presenter = new SwapChainGraphicsPresenter(device, desc); Defensive patterns
Strategy: validation
Validate before calling
if (swapChainDescription.DeviceWindowHandle == null)
throw new InvalidOperationException("Set DeviceWindowHandle before creating the SwapChainGraphicsPresenter"); Type guard
bool HasWindowHandle(SwapChainDescription d) => d.DeviceWindowHandle is not null;
Try / catch
try { presenter = new SwapChainGraphicsPresenter(device, desc); }
catch (ArgumentException ex) when (ex.Message.Contains("DeviceWindowHandle cannot be null")) { log.Error("No window handle configured for swapchain", ex); throw; } Prevention
- Initialize the game window before creating graphics device/presenter
- Always set Game.Window handle into SwapChainDescription.DeviceWindowHandle
- Use headless/offscreen APIs for rendering without a window
- Add an early config check that the window handle is assigned
When it happens
Trigger: Constructing or recreating a SwapChainGraphicsPresenter with a SwapChainDescription whose DeviceWindowHandle was never set (null).
Common situations: Building a Game/graphics context programmatically and forgetting to assign Game.Window / DeviceWindowHandle; creating the presenter before the game window exists; copying a description struct that dropped the handle.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- DeviceWindowHandle cannot be null
- The . must not be zero.
- resource
- commandLists
- Required Vulkan extension
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/e7334a9eb38eaec7.
Report an issue: GitHub.
Appendix: source
Thrown at sources/engine/Stride.Graphics/Vulkan/SwapChainGraphicsPresenter.Vulkan.cs:552
private unsafe void RecreateSurface()
{
// Swapchain must be torn down before the surface (Vulkan spec + Android ANativeWindow exclusivity).
DestroySwapchain();
if (surface != VkSurfaceKHR.Null)
{
GraphicsDevice.NativeInstanceApi.vkDestroySurfaceKHR(GraphicsDevice.NativeInstance, surface, null);
surface = VkSurfaceKHR.Null;
}
CreateSurface();
}
private unsafe void CreateSurface()
{
// Check for Window Handle parameter
if (Description.DeviceWindowHandle == null)
{
throw new ArgumentException("DeviceWindowHandle cannot be null");
}
// Validate surface extension support (not available with headless ICDs)
if (!GraphicsAdapterFactory.GetInstance(GraphicsDevice.IsDebugMode).HasSurfaceSupport)
throw new InvalidOperationException("Cannot create a swapchain: Vulkan surface extensions are not available. This may happen when using a headless ICD.");
// Create surface
#if STRIDE_UI_SDL
// iOS reuses the SDL surface-creation path (GameContextiOS inherits GameContextSDL);
// SDL's VulkanCreateSurface routes to VkMetalSurfaceCreateInfoEXT internally on iOS.
if (Description.DeviceWindowHandle.Context == Games.AppContextType.DesktopSDL
|| Description.DeviceWindowHandle.Context == Games.AppContextType.iOS)
{
var control = Description.DeviceWindowHandle.NativeWindow as SDL.Window;
Silk.NET.Core.Native.VkNonDispatchableHandle surfaceHandle = default;
SDL.Window.SDL.VulkanCreateSurface((Silk.NET.SDL.Window*)control.SdlHandle, new Silk.NET.Core.Native.VkHandle(GraphicsDevice.NativeInstance.Handle), ref surfaceHandle);
surface = new VkSurfaceKHR(surfaceHandle.Handle);
}View on GitHub (pinned to 96fad776d2)