In my opinion if, uring the traversal, you assign a null value to an existent field on the table, this also causes an undefined behavior for iterators: it causes the key to be unassigned, the table may be flushed/cleaned/reindexed.
Any kind of modification of the content of a table, even on its existing keys, can cause this behavior, including in sequence-tables (tables indexed by positive integers in a continuous range, where assigning too many nil values to some positions could as well remove the integer-based array and force the remaining keys to be indexed in the hashed part instead). Setting an index position to nil and back to the original non-nil value may as well not restore a state usable for existing iterators as the table could be reorganized differently.
If you want stable iterators, on a table you intend to modify, you always need to create a shallow copy of its key index and their values (numbers, string, simple types), or references (to tables/thread objects/userdata...). This requires making some allocation. In Lua there's no way to makr a table to be readonly and create instantly a new shallow copy for the modifiable version, so that the readonly version will remaing valid as long as there's an iterator on it. But that's something that could be part of tables implementations and internal implementations of iterators (to automatically create the shallow readonly copies and free them up automatically as soon as all iterators have reached the end or the iterator has become unreachable and is garbage collected. This would require more work in the garbage collector. But tables in Lua are used so much that it would be very interesting to integrate that in the Lua core itself.
This would finally completely remove the "undefined behavior", would suppress various security risks (notably denial of services caused by endless loops, or crashes caused by unbound allocations of memory and the code exhausting all usable resource quotas).
Tables are still the weakest part of Lua, making it very fragile, and easily attackable. This means that Lua is hardly usable for online web services in shared worker threads used by many concurrent users Lua is TOO simple, but TOO easily attackable, and this unsafe status means that many projects have abandoned it for use on the web, or have had to implement stricter resource quotas checks to avoid crashing servers, but in that case lot of pages can fail to render at any time, unpredictably. And it's impossible to enforce any safe environment and stability: Lua is then outlawed for any critical missions, notably in applications using any kind private user data, and in fact this includes almost applications oàn the web, so user data collection is unavoidable and frequently even required by law): Lua is too dangerous except for non-critical apps using
public data, and with failover mechanisms if one server crashes.
Java and even C++ can be safer). If Lua does not solve this problem, it will fatally be abandoned by many people.