stride3d/stride · error · InvalidOperationException
Inconsistency: two tetrahedra don't agree on their…
Error message
Inconsistency: two tetrahedra don't agree on their neighbour information (they should both reference each other)
What it means
CheckConnectivity (invoked from the BowyerWatsonTetrahedralization constructor) validates that neighbouring tetrahedra reference each other symmetrically. When a tetrahedron lists a neighbour, but that neighbour's own Neighbours array has no slot pointing back, the invariant is broken and InvalidOperationException is thrown.
Solutions
- Verify probe positions don't contain duplicates or near-degenerate configurations that stress the algorithm
- Reduce/simplify the probe layout and retry baking
- Report to Stride as an internal tetrahedralization bug if reproducible with a simple probe group
Defensive patterns
Strategy: try-catch
Validate before calling
if (probes.Select(p => p).Distinct().Count() != probes.Count)
throw new ArgumentException("Duplicate probes can break tetrahedralization"); Try / catch
try { var t = new BowyerWatsonTetrahedralization(vertices); }
catch (InvalidOperationException e) { logger.Error(e, "Tetrahedralization connectivity failure"); /* fall back to brute-force lookup */ } Prevention
- Report persistent occurrences as engine bugs
- Use well-spaced, non-degenerate probe layouts
- Keep probe groups modest in size when baking
When it happens
Trigger: A bug condition in AddVertex's cavity re-triangulation where an edge's recorded neighbour index doesn't match any face of the neighbour tetrahedron, detected during the constructor's connectivity pass.
Common situations: Practically only hit during light-probe baking on tetrahedralizations with many probes where numeric edge bookkeeping can diverge; indicates an engine bug rather than user error.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- Internal error, the collection has already muted to a…
- parent cannot be null
- Tetrahedron not in positive order
- The first lock in the queue was not the current lock
- A file path cannot end with with directory char '\' or '/'…
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/2aed5d00f19d383e.
Report an issue: GitHub.
Appendix: source
Thrown at sources/engine/Stride.Rendering/Rendering/LightProbes/BowyerWatsonTetrahedralization.cs:484
// If edge is not shared by any other bad tetrahedra, it means it's a boundary of our polygonal hole
var neighbourTetrahedronIndex = tetrahedron->Neighbours[i];
if (badTetrahedra.BinarySearch(neighbourTetrahedronIndex) < 0)
{
var neighbourTetrahedronSelfIndex = -1;
if (neighbourTetrahedronIndex != -1)
{
// Find the neighbour index of current tetrahedra in neighbourTetrahedra
var neighbourTetrahedron = &tetrahedra[neighbourTetrahedronIndex];
for (int j = 0; j < 4; ++j)
{
if (neighbourTetrahedron->Neighbours[j] == tetrahedronIndex)
{
neighbourTetrahedronSelfIndex = j;
break;
}
}
if (neighbourTetrahedronSelfIndex == -1)
throw new InvalidOperationException("Inconsistency: two tetrahedra don't agree on their neighbour information (they should both reference each other)");
}
// Store edges information (to easily reconstruct neighbour after)
var vertex0 = tetrahedron->Vertices[(i + 1) % 4];
var vertex1 = tetrahedron->Vertices[(i + 2) % 4];
var vertex2 = tetrahedron->Vertices[(i + 3) % 4];
// If new vertex is at an odd position, it means that newly constructed tetrahedron would have a negative order, let's swap 2 vertices
//if (!IsTetrahedraPositiveOrder(ref vertex, ref vertices[vertex0], ref vertices[vertex1], ref vertices[vertex2]))
if (i % 2 == 1)
{
var vertexTemp = vertex1;
vertex1 = vertex2;
vertex2 = vertexTemp;
}
if (!IsTetrahedronPositiveOrder(ref vertex, ref vertices[vertex0], ref vertices[vertex1], ref vertices[vertex2]))
throw new InvalidOperationException();View on GitHub (pinned to 96fad776d2)