{"record":{"id":"8648cae7f53a0729","repo":"stride3d/stride","slug":"invalid-source-ienumerable","errorCode":null,"errorMessage":"Invalid 'source' IEnumerable.","messagePattern":"Invalid 'source' IEnumerable\\.","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"sources/core/Stride.Core/Extensions/EnumerableExtensions.cs","lineNumber":22,"sourceCode":"using System.Collections;\nusing System.Diagnostics.Contracts;\n\nnamespace Stride.Core.Extensions;\n\npublic static class EnumerableExtensions\n{\n    /// <summary>\n    /// Tells whether a sequence is null or empty.\n    /// </summary>\n    /// <param name=\"source\">The source sequence.</param>\n    /// <returns>Returns true if the sequence is null or empty, false if it is not null and contains at least one element.</returns>\n    [Pure]\n    public static bool IsNullOrEmpty(this IEnumerable? source)\n    {\n        if (source == null)\n            return true;\n\n        var enumerator = source.GetEnumerator() ?? throw new ArgumentException(\"Invalid 'source' IEnumerable.\");\n        return enumerator.MoveNext() == false;\n    }\n\n    /// <summary>\n    /// Executes an action for each (casted) item of the given enumerable.\n    /// </summary>\n    /// <typeparam name=\"T\">Type of the item value in the enumerable.</typeparam>\n    /// <param name=\"source\">Input enumerable to work on.</param>\n    /// <param name=\"action\">Action performed for each item in the enumerable.</param>\n    /// <remarks>This extension method do not yield. It acts just like a foreach statement, and performs a cast to a typed enumerable in the middle.</remarks>\n    public static void ForEach<T>(this IEnumerable source, Action<T> action)\n    {\n        source.Cast<T>().ForEach(action);\n    }\n\n    /// <summary>\n    /// Executes an action for each item of the given enumerable.\n    /// </summary>","sourceCodeStart":4,"sourceCodeEnd":40,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/core/Stride.Core/Extensions/EnumerableExtensions.cs#L4-L40","documentation":"EnumerableExtensions.IsNullOrEmpty checks whether an IEnumerable is null or has no elements by obtaining its enumerator. If source.GetEnumerator() returns null (legal for a null-returning custom implementation), it throws ArgumentException with the message \"Invalid 'source' IEnumerable.\". This is a defensive check for broken IEnumerable implementations, not for a null source (which is handled by returning true).","triggerScenarios":"Passing an IEnumerable whose GetEnumerator() method returns null — e.g. a mis-implemented custom collection, a stub/mock returning null, or an exotic enumerable wrapper that yields no enumerator.","commonSituations":"Mocking IEnumerable in unit tests with a stub whose GetEnumerator returns null; custom lazy/streaming collections that fail to produce an enumerator; calling IsNullOrEmpty on a structurally broken third-party collection.","solutions":["Fix the IEnumerable implementation so GetEnumerator() returns a valid non-null IEnumerator (or throw, or return an empty enumerator)","Do not mock with null enumerators; have test stubs return IEnumerator.Empty-style empty enumerators","If you must test suspicious sources, wrap the call in try/catch for ArgumentException","Prefer checking source == null and using Any()/Count with a working collection before relying on IsNullOrEmpty"],"exampleFix":"// before\npublic IEnumerator GetEnumerator() => null; // broken stub\n// after\npublic IEnumerator GetEnumerator() => Array.Empty<object>().GetEnumerator();","handlingStrategy":"type-guard","validationCode":"if (source == null) return true;\nif (source.GetEnumerator() is null)\n    throw new ArgumentException(\"Source must return a valid enumerator.\");","typeGuard":"static bool IsValidEnumerable(IEnumerable? source) =>\n    source == null || source.GetEnumerator() != null;","tryCatchPattern":"try\n{\n    bool empty = enumerable.IsNullOrEmpty();\n}\ncatch (ArgumentException ex) when (ex.Message == \"Invalid 'source' IEnumerable.\")\n{\n    // source is a broken IEnumerable: fix or replace the implementation\n}","preventionTips":["Never return null from GetEnumerator in custom collections; return an empty enumerator instead","Check that test mocks of IEnumerable return a real enumerator","Prefer Any() on verified non-null collections when implementations are trusted"],"tags":["csharp","ienumerable","argumentexception"],"backgroundTag":"invalid-argument-value","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"}