stride3d/stride · error · InvalidOperationException

Cannot clear a stencil buffer without a Stencil Buffer…

Error message

Cannot clear a stencil buffer without a Stencil Buffer format [{0}].

What it means

Thrown by CommandList.Clear when ClearDepthStencilClearOptions.Stencil is requested but the depth-stencil buffer's format has no stencil component (e.g. D32Float, D16). An InvalidOperationException carries the offending ViewFormat so the developer can see why. D3D11 cannot clear stencil on a stencil-less view.

Solutions

  1. Remove DepthStencilClearOptions.Stencil from the options when the buffer format has no stencil.
  2. Recreate the depth-stencil buffer with a format that includes stencil (e.g. PixelFormat.D24_UNORM_S8_UInt or D32FloatS8X24).
  3. Check depthStencilBuffer.HasStencil at the call site and clear stencil conditionally.

Example fix

// before
commandList.Clear(depthBuffer, DepthStencilClearOptions.DepthBuffer | DepthStencilClearOptions.Stencil);
// after
var options = DepthStencilClearOptions.DepthBuffer;
if (depthBuffer.HasStencil) options |= DepthStencilClearOptions.Stencil;
commandList.Clear(depthBuffer, options);
Defensive patterns

Strategy: validation

Validate before calling

var options = DepthStencilClearOptions.DepthBuffer;
if (wantStencil && depthStencilBuffer.HasStencil)
    options |= DepthStencilClearOptions.Stencil;
commandList.Clear(depthStencilBuffer, options);

Type guard

static bool CanClearStencil(Texture ds) => ds is not null && ds.HasStencil;

Try / catch

try { commandList.Clear(ds, opts); }
catch (InvalidOperationException ex) when (ex.Message.Contains("Stencil")) { commandList.Clear(ds, DepthStencilClearOptions.DepthBuffer); }

Prevention

When it happens

Trigger: Calling commandList.Clear(depthStencilBuffer, DepthStencilClearOptions.DepthBuffer | DepthStencilClearOptions.Stencil, ...) where the buffer's format is a depth-only format without stencil (D16, D32, D32Float).

Common situations: Reusing a shared clear helper across depth-stencil textures created with different formats; a format switch from D24S8 to D32Float that kept stencil-clear flags; clearing render targets and depth buffers in one generic pass.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14). Data as JSON: /api/errors/bda871f0a8f54cf5. Report an issue: GitHub.

Appendix: source

Thrown at sources/engine/Stride.Graphics/Direct3D11/CommandList.Direct3D11.cs:916

        /// <param name="options">
        ///   A combination of <see cref="DepthStencilClearOptions"/> flags identifying what parts of the Depth-Stencil Buffer to clear.
        /// </param>
        /// <param name="depth">The depth value to use for clearing the Depth Buffer.</param>
        /// <param name="stencil">The stencil value to use for clearing the Stencil Buffer.</param>
        /// <exception cref="ArgumentNullException"><paramref name="depthStencilBuffer"/> is <see langword="null"/>.</exception>
        /// <exception cref="InvalidOperationException">Cannot clear a Stencil Buffer without a Stencil Buffer format.</exception>
        public void Clear(Texture depthStencilBuffer, DepthStencilClearOptions options, float depth = 1, byte stencil = 0)
        {
            ArgumentNullException.ThrowIfNull(depthStencilBuffer);
            RecordDebugCounter(DebugCounterKind.Clear);

            var flags = options.HasFlag(DepthStencilClearOptions.DepthBuffer) ? ClearFlag.Depth : 0;

            // Check that the Depth-Stencil Buffer has a Stencil if Clear Stencil is requested
            if (options.HasFlag(DepthStencilClearOptions.Stencil))
            {
                if (!depthStencilBuffer.HasStencil)
                    throw new InvalidOperationException(string.Format(FrameworkResources.NoStencilBufferForDepthFormat, depthStencilBuffer.ViewFormat));

                flags |= ClearFlag.Stencil;
            }

            nativeDeviceContext->ClearDepthStencilView(depthStencilBuffer.NativeDepthStencilView, (uint) flags, depth, stencil);
        }

        /// <summary>
        ///   Clears the specified Render Target.
        /// </summary>
        /// <param name="renderTarget">The Render Target to clear.</param>
        /// <param name="color">The color to use to clear the Render Target.</param>
        /// <exception cref="ArgumentNullException"><paramref name="renderTarget"/> is <see langword="null"/>.</exception>
        public void Clear(Texture renderTarget, Color4 color)
        {
            ArgumentNullException.ThrowIfNull(renderTarget);
            RecordDebugCounter(DebugCounterKind.Clear);

View on GitHub (pinned to 96fad776d2)