[.NET 10 servicing] Backport #123295: Skip() past the end followed by Concat() still throws ArgumentOutOfRangeException on 10.0.12
Maintainers usually reply within 1 day
Nobody has claimed this yet.
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 88/100
Research direction
Start in src/libraries/System.Linq/src/System/Linq/SkipTake.SpeedOpt.cs on release/10.0 and compare the affected method with its main-branch version from #123295. Run the attached net10.0 repro to confirm the Concat().ToArray() failure and verify that the backport produces 1 element without an exception.
Written by the indexing model from the issue text.
Description
Summary
Requesting a release/10.0 backport of #123295, which fixed #123284 on main on 2026-01-20. The bug is a regression in a GA LTS release (introduced by #112401 in .NET 10), the fix is a one-line bounds check, and it is still present in the current servicing release. #123284 is locked, so this is filed separately rather than as a comment there.
Still reproduces on .NET 10.0.12
Microsoft.NETCore.App 10.0.12, Windows x64, Release, net10.0 console app (two-file repro attached below):
.NET 10.0.12
array.Skip(2).ToArray() -> 0 element(s)
array.Take(2).Concat(array.Skip(2)).ToArray() -> THREW ArgumentOutOfRangeException: Specified argument was out of the range of valid values.
at System.Linq.Enumerable.IListSkipTakeIterator`1.Fill(IList`1 source, Span`1 destination, Int32 sourceIndex)
at System.Linq.Enumerable.IListSkipTakeIterator`1.CopyTo(TSource[] array, Int32 arrayIndex)
at System.Linq.Enumerable.Concat2Iterator`1.ToArray()
list.Take(2).Concat(list.Skip(2)).ToArray() -> THREW ArgumentOutOfRangeException (same stack)
Bare Skip(n).ToArray() past the end is fine; the throw is in the CopyTo/Fill path that Concat (and anything else that fills from the iterator) uses.
Branch state
main:src/libraries/System.Linq/src/System/Linq/SkipTake.SpeedOpt.csguards the copy withif (sourceIndex < sourceSpan.Length)(from #123295).release/10.0: the same method still readssourceSpan.Slice(sourceIndex, destination.Length).CopyTo(destination);unconditionally (line 151 as of 2026-09-27).- No
[release/10.0]PR references #123284 or #123295.
Impact
Hit in March 2026 in a production WinForms application after moving to .NET 10. A number-format helper did parts.Take(2).Select(...).Concat(parts.Skip(2)).ToArray() over the ;-separated sections of a .NET numeric format string; every single-section format ("N2", the common case) threw from ToArray() on a code path that had been stable since .NET Framework. "Take the first N, transform them, append the rest" is ordinary LINQ, and nothing in the exception points at Skip, so it is expensive to diagnose from the call site. The workaround (Skip(Math.Min(n, source.Length))) is not something most codebases will know to reach for, and the fix already exists.
Repro
using System.Runtime.InteropServices;
Console.WriteLine(RuntimeInformation.FrameworkDescription);
string[] one = ["N2"];
try
{
Console.WriteLine(one.Take(2).Concat(one.Skip(2)).ToArray().Length + " element(s)");
}
catch (Exception e)
{
Console.WriteLine($"{e.GetType().Name}: {e.Message}");
}
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net10.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
</Project>
Expected: 1 element(s). Actual on 10.0.12: ArgumentOutOfRangeException: Specified argument was out of the range of valid values.
Related
- Regression: #112401 (Improve Enumerable.Skip and Enumerable.Take performance)
- Report: #123284
- Fix on
main: #123295
- Dominant language
- C#
- Stars
- 18.3k
- Forks
- 5.6k
- Avg merge
- 2d 20h
- Merged PRs (30d)
- 614
Getting set up
Starts the project's dev container in your browser, under your own GitHub account.
- No Dockerfile or Docker Compose file
- Has a pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from dotnet/runtime
-
area-System.Memory untriaged
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
dotnet/runtime#134840 · 4 comments · 1 reaction ·
Maintainers usually reply within 1 day
-
area-System.Numerics.Tensors untriaged
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
dotnet/runtime#134691 · 2 comments ·
Maintainers usually reply within 1 day
-
area-System.Threading blocking-clean-ci Known Build Error untriaged
Difficulty 2/5 1-3 hours Newbie friendliness 70/100
dotnet/runtime#134679 · 4 comments ·
Maintainers usually reply within 1 day
-
ARM64: conditional compare rejects negative immediates the emitter can already encode as `ccmn`Openarea-CodeGen-coreclr performance
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
dotnet/runtime#134663 · 1 comment ·
Maintainers usually reply within 1 day
-
area-System.Security untriaged
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
dotnet/runtime#134659 · 1 comment ·
Maintainers usually reply within 1 day
Similar issues
-
:watch: Not Triaged dotnet-target-version
Difficulty 1/5 Under an hour Newbie friendliness 85/100
Maintainers usually reply within 1 day
-
copilot documentation
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
Maintainers usually reply within 2 days
-
untriaged
Difficulty 2/5 1-3 hours Newbie friendliness 86/100
dotnet/dotnet-api-docs#13124 ·
Maintainers usually reply within 1 day
-
agentic-workflows
Difficulty 2/5 1-3 hours Newbie friendliness 74/100
Maintainers usually reply within 1 day
-
type:bug
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
BHoM/MidasCivil_Toolkit#441 ·