stride3d/stride · error · ArgumentException
Control points apply only to PrimitiveType.PatchList
Error message
Control points apply only to PrimitiveType.PatchList
What it means
This extension method returns a PrimitiveType configured with a control-point count, which is meaningful only for tessellation (PrimitiveType.PatchList). Calling it on any other primitive type throws ArgumentException naming the 'primitiveType' parameter. A subsequent validation bounds control points to 1..32.
Solutions
- Use PrimitiveType.PatchList.ControlPointCount(n) when configuring hull/tessellation stages.
- Only call ControlPointCount for tessellated pipelines; keep the plain primitive type otherwise.
- Validate the primitive type from configuration before invoking.
Example fix
// before var type = PrimitiveType.TriangleList.ControlPointCount(3); // throws // after var type = PrimitiveType.PatchList.ControlPointCount(3);
Defensive patterns
Strategy: type-guard
Validate before calling
if (primitiveType != PrimitiveType.PatchList)
throw new InvalidOperationException("ControlPointCount requires PatchList");
if (controlPoints is < 1 or > 32)
throw new ArgumentOutOfRangeException(nameof(controlPoints)); Type guard
bool IsPatchList(PrimitiveType t) => t == PrimitiveType.PatchList;
Try / catch
try { type = primitiveType.ControlPointCount(n); }
catch (ArgumentException ex) { log.Error("control points need PatchList", ex); } Prevention
- Call ControlPointCount only when setting up tessellation
- Validate primitive type coming from config/assets
- Remember control point range is 1..32
When it happens
Trigger: Calling primitiveType.ControlPointCount(n) where primitiveType is not PatchList, e.g. TriangleList, LineStrip, or a default PrimitiveType value.
Common situations: Configuring tessellation stages with a generic primitive type; a settings/asset pipeline supplying a non-patch primitive type; misunderstanding that all PrimitiveType values accept control points.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- Invalid Z slice index
- MipLevels must be <=
- Width/Height/Depth must be power of 2
- Image format not supported
- This file format is not yet implemented.
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/0c6f9fb7876b9797.
Report an issue: GitHub.
Appendix: source
Thrown at sources/engine/Stride.Graphics/PrimitiveTypeExtensions.cs:26
/// <summary>
/// Defines extensions and helpers for <see cref="PrimitiveType"/>.
/// </summary>
public static class PrimitiveTypeExtensions
{
/// <summary>
/// Interpret the input vertex data type as a <strong>patch list</strong> for tesselation with a
/// specific number of <strong>control points</strong>.
/// </summary>
/// <param name="controlPoints">The number of control points. It must be a value in the range 1 to 32, inclusive.</param>
/// <returns>
/// A <see cref="PrimitiveType"/> value that represents a patch list with the specified number of control points.
/// </returns>
/// <exception cref="ArgumentException">Control points apply only to <see cref="PrimitiveType.PatchList"/>.</exception>
/// <exception cref="ArgumentOutOfRangeException"><paramref name="controlPoints"/> must be in the range 1 to 32, inclusive.</exception>"
public static PrimitiveType ControlPointCount(this PrimitiveType primitiveType, int controlPoints)
{
if (primitiveType != PrimitiveType.PatchList)
throw new ArgumentException($"Control points apply only to {nameof(PrimitiveType)}.{nameof(PrimitiveType.PatchList)}", nameof(primitiveType));
const int MIN_CONTROL_POINTS = 1, MAX_CONTROL_POINTS = 32;
if (controlPoints < MIN_CONTROL_POINTS || controlPoints > MAX_CONTROL_POINTS)
throw new ArgumentOutOfRangeException(nameof(controlPoints), $"Value must be in between {MIN_CONTROL_POINTS} and {MAX_CONTROL_POINTS}");
return PrimitiveType.PatchList + controlPoints - 1;
}
}
View on GitHub (pinned to 96fad776d2)