{"record":{"id":"e71a4376bc02ed4b","repo":"stride3d/stride","slug":"setdescriptor-should-not-call-function-removeat","errorCode":null,"errorMessage":"SetDescriptor should not call function 'RemoveAt'.","messagePattern":"SetDescriptor should not call function 'RemoveAt'\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"sources/core/Stride.Core.Reflection/TypeDescriptors/SetDescriptor.cs","lineNumber":108,"sourceCode":"    public override void Insert(object set, int index, object? value)\n    {\n        throw new InvalidOperationException(\"SetDescriptor should not call function 'Insert'.\");\n    }\n\n    /// <summary>\n    /// Remove a value from a set\n    /// </summary>\n    /// <param name=\"set\">The set.</param>\n    /// <param name=\"key\">The key.</param>\n    public override void Remove(object set, object? key)\n    {\n        ArgumentNullException.ThrowIfNull(set);\n        removeMethod.Invoke(set, key);\n    }\n\n    public override void RemoveAt(object set, int index)\n    {\n        throw new InvalidOperationException($\"{nameof(SetDescriptor)} should not call function 'RemoveAt'.\");\n    }\n\n    /// <summary>\n    /// Clears the specified set.\n    /// </summary>\n    /// <param name=\"set\">The set.</param>\n    public override void Clear(object set)\n    {\n        clearMethod.Invoke(set);\n    }\n\n    /// <summary>\n    /// Indicate whether the set contains the given value\n    /// </summary>\n    /// <param name=\"set\">The set.</param>\n    /// <param name=\"value\">The value.</param>\n    public bool Contains(object set, object? value)\n    {","sourceCodeStart":90,"sourceCodeEnd":126,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/core/Stride.Core.Reflection/TypeDescriptors/SetDescriptor.cs#L90-L126","documentation":"SetDescriptor.RemoveAt mirrors Insert: sets have no positional elements, so removal by index is impossible. The descriptor deliberately throws InvalidOperationException to signal that index-based removal was invoked on an unordered set. Use Remove with the actual key/item instead.","triggerScenarios":"Calling SetDescriptor.RemoveAt(set, index) directly, or generic list-style collection manipulation code applying RemoveAt to a set descriptor.","commonSituations":"Shared collection-editing UI or serializer code paths that assume IList semantics; refactored code that switched a property from List<T> to HashSet<T> without updating index-based edits.","solutions":["Call Remove(object set, object key) with the item itself instead of RemoveAt","Guard with `if (descriptor is SetDescriptor)` before using positional APIs","Switch to a list-backed type if index-based removal is genuinely required"],"exampleFix":"// before\ndescriptor.RemoveAt(mySet, 2);\n// after\ndescriptor.Remove(mySet, itemToRemove);","handlingStrategy":"validation","validationCode":"if (descriptor is SetDescriptor)\n    descriptor.Remove(set, item);\nelse\n    descriptor.RemoveAt(set, index);","typeGuard":"bool IsSetDescriptor(object d) => d is SetDescriptor;","tryCatchPattern":null,"preventionTips":["Use Remove(item) for sets, RemoveAt(index) only for lists","Special-case set descriptors in generic collection editors","Re-check code after switching property types between List and HashSet"],"tags":["reflection","unsupported-operation","sets"],"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"}