{"record":{"id":"7d402d194b13d8fc","repo":"stride3d/stride","slug":"collection-is-read-only","errorCode":null,"errorMessage":"Collection is read only","messagePattern":"Collection is read only","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"sources/engine/Stride.Physics/Shapes/StaticMeshColliderShape.cs","lineNumber":257,"sourceCode":"            }\n\n            public int Count => internalColl.Count;\n\n            public bool IsReadOnly => true;\n\n            public bool Contains(BulletSharp.Math.Vector3 item) => internalColl.Contains(item);\n\n            public void CopyTo(BulletSharp.Math.Vector3[] array, int arrayIndex)\n            {\n                foreach (var value in internalColl)\n                {\n                    if (arrayIndex >= array.Length)\n                        return;\n                    array[arrayIndex++] = value;\n                }\n            }\n\n            public void Add(BulletSharp.Math.Vector3 item) => throw new InvalidOperationException(\"Collection is read only\");\n            public bool Remove(BulletSharp.Math.Vector3 item) => throw new InvalidOperationException(\"Collection is read only\");\n            public void Clear() => throw new InvalidOperationException(\"Collection is read only\");\n\n            public IEnumerator<BulletSharp.Math.Vector3> GetEnumerator()\n            {\n                foreach (var value in internalColl)\n                    yield return value;\n            }\n\n            IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();\n        }\n    }\n}\n","sourceCodeStart":239,"sourceCodeEnd":271,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/engine/Stride.Physics/Shapes/StaticMeshColliderShape.cs#L239-L271","documentation":"StrideToBulletWrapper is a read-only IList<BulletSharp.Math.Vector3> adapter that maps Stride vectors to Bullet vectors for the physics backend. Mutating members are explicitly implemented to throw InvalidOperationException('Collection is read only') because the wrapper forwards to an immutable underlying buffer.","triggerScenarios":"Calling Add on a Vector3 collection obtained through StrideToBulletWrapper — e.g. attempting to add vertices to a static mesh collider's point collection after creation.","commonSituations":"Treating the collider's vertex collection like a growable List<T>; code written for mutable collections (ICollection.Add) being reused against the read-only wrapper; refactoring that changed a List into the Bullet wrapper.","solutions":["Build the vertex data in a regular List<BulletSharp.Math.Vector3> first, then construct the StaticMeshColliderShape from it","Treat the collection as read-only — do not call Add/Remove/Clear on it; use indexing/enumeration only","Replace the wrapper usage with a mutable collection type if mutation is genuinely required"],"exampleFix":"// before\nvar points = staticMeshShape.Points; // StrideToBulletWrapper, read-only\npoints.Add(new Vector3(1, 2, 3)); // throws\n\n// after\nvar points = new List<BulletSharp.Math.Vector3> { new Vector3(1, 2, 3) };\nvar shape = new StaticMeshColliderShape(points, indices);","handlingStrategy":"type-guard","validationCode":"if (points is ICollection<BulletSharp.Math.Vector3> c && c.IsReadOnly)\n    throw new NotSupportedException(\"Point collection is read-only; build data elsewhere first\");","typeGuard":"bool IsMutableVectorList(object coll) =>\n    coll is ICollection<BulletSharp.Math.Vector3> c && !c.IsReadOnly;","tryCatchPattern":"try { points.Add(item); }\ncatch (InvalidOperationException ex) when (ex.Message == \"Collection is read only\")\n{\n    var buffer = new List<BulletSharp.Math.Vector3>(points) { item };\n    shape = new StaticMeshColliderShape(buffer, indices);\n}","preventionTips":["Treat any collection exposed by a collider shape as read-only; compose vertex data in your own List first","Check ICollection.IsReadOnly before calling Add/Remove/Clear on any physics collection","Never mutate mesh data after the collider shape has been created — rebuild the shape instead"],"tags":["physics","read-only","collection","unsupported-operation"],"backgroundTag":"unsupported-operation","analyzedSha":"96fad776d210c221682aac1ccdf4c79dc046fc38","analyzedAt":"2026-09-14T02:59:31.279Z","contentChangedAt":"2026-09-14T02:59:31.279Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}