With this we have to ask how is the 'items' enumerable produced? Is it a yield
block? Use of yield blocks can suffer from the spectre of delayed execution (i.e. the enumerable not being prepared until the enumerator is accessed) and you can unexpected results from this.
Assuming that the Exception is being thrown from the items enumerator, then the only reason for it to be thrown is if the collection has been modified. Unless it's a custom class implementing its own enumerator, in which case there could simply be a bug in it.
You've discounted the multithreaded environment so I'll ignore that possibility.
Do you still get the error if you 'realise' the enumerable - i.e.
foreach(var item in items.ToArray())
{
//your code.
}
I'll bet you don't, and if not, then something is definitely modifying your items list.
You could check that items
and the result of the .ToArray() call above (you'd have to cache it to a local variable) are still the same at the end of your foreach loop.