{"record":{"id":"d5e11f83e544cce3","repo":"Cysharp/UniTask","slug":"use-foreachawaitasync-instead","errorCode":null,"errorMessage":"Use ForEachAwaitAsync instead.","messagePattern":"Use ForEachAwaitAsync instead\\.","errorType":"exception","errorClass":"NotSupportedException","httpStatus":null,"severity":"error","filePath":"src/UniTask/Assets/Plugins/UniTask/Runtime/Linq/ForEach.cs","lineNumber":30,"sourceCode":"            Error.ThrowArgumentNullException(action, nameof(action));\n\n            return Cysharp.Threading.Tasks.Linq.ForEach.ForEachAsync(source, action, cancellationToken);\n        }\n\n        public static UniTask ForEachAsync<TSource>(this IUniTaskAsyncEnumerable<TSource> source, Action<TSource, Int32> action, CancellationToken cancellationToken = default)\n        {\n            Error.ThrowArgumentNullException(source, nameof(source));\n            Error.ThrowArgumentNullException(action, nameof(action));\n\n            return Cysharp.Threading.Tasks.Linq.ForEach.ForEachAsync(source, action, cancellationToken);\n        }\n\n        /// <summary>Obsolete(Error), Use Use ForEachAwaitAsync instead.</summary>\n        [Obsolete(\"Use ForEachAwaitAsync instead.\", true)]\n        [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]\n        public static UniTask ForEachAsync<T>(this IUniTaskAsyncEnumerable<T> source, Func<T, UniTask> action, CancellationToken cancellationToken = default)\n        {\n            throw new NotSupportedException(\"Use ForEachAwaitAsync instead.\");\n        }\n\n        /// <summary>Obsolete(Error), Use Use ForEachAwaitAsync instead.</summary>\n        [Obsolete(\"Use ForEachAwaitAsync instead.\", true)]\n        [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]\n        public static UniTask ForEachAsync<T>(this IUniTaskAsyncEnumerable<T> source, Func<T, int, UniTask> action, CancellationToken cancellationToken = default)\n        {\n            throw new NotSupportedException(\"Use ForEachAwaitAsync instead.\");\n        }\n\n        public static UniTask ForEachAwaitAsync<TSource>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, UniTask> action, CancellationToken cancellationToken = default)\n        {\n            Error.ThrowArgumentNullException(source, nameof(source));\n            Error.ThrowArgumentNullException(action, nameof(action));\n\n            return Cysharp.Threading.Tasks.Linq.ForEach.ForEachAwaitAsync(source, action, cancellationToken);\n        }\n","sourceCodeStart":12,"sourceCodeEnd":48,"githubUrl":"https://github.com/Cysharp/UniTask/blob/ceac8d6946b1125fe782cd171fbcb245b567dbf9/src/UniTask/Assets/Plugins/UniTask/Runtime/Linq/ForEach.cs#L12-L48","documentation":"Thrown (and emitted as a compile-time error via [Obsolete(..., true)]) by the ForEachAsync extension on IUniTaskAsyncEnumerable<T> taking Func<T, UniTask>. This overload was removed because the name 'ForEachAsync' was ambiguous about whether the async action is awaited per-element. The replacement is ForEachAwaitAsync which makes the await semantics explicit.","triggerScenarios":"Calling source.ForEachAsync(async x => await ProcessAsync(x)) on an IUniTaskAsyncEnumerable<T>. The [Obsolete(true)] attribute makes this a hard compile error; the runtime throw is a fallback for reflection/dynamic invocation.","commonSituations":"Upgrading UniTask from a version that had this overload. Copying code from outdated tutorials or Stack Overflow answers. Migration from System.Threading.Tasks extensions where ForEachAsync is the standard name.","solutions":["Rename the call from ForEachAsync to ForEachAwaitAsync (same signature).","If the action is synchronous (Func<T, void>), use the non-generic ForEachAsync overload that accepts a synchronous action — that overload is not obsolete."],"exampleFix":"// before\nawait source.ForEachAsync(async x => await ProcessAsync(x));\n\n// after\nawait source.ForEachAwaitAsync(async x => await ProcessAsync(x));","handlingStrategy":"validation","validationCode":"// This is a compile-time error — fix at the call site.\n// Replace ForEachAsync with ForEachAwaitAsync for async actions:\nawait source.ForEachAwaitAsync(async x => await ProcessAsync(x));\n// For synchronous actions, the non-obsolete overload is fine:\nawait source.ForEachAsync(x => ProcessSync(x));","typeGuard":null,"tryCatchPattern":null,"preventionTips":["When upgrading UniTask, search your codebase for 'ForEachAsync' and migrate to ForEachAwaitAsync.","Bookmark the current UniTask API docs to avoid referencing outdated examples."],"tags":["obsolete","migration","linq","breaking-change"],"backgroundTag":null,"analyzedSha":"ceac8d6946b1125fe782cd171fbcb245b567dbf9","analyzedAt":"2026-08-13T19:16:39.025Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}