Skip to content

InvalidOperationException when ticking quests during async time due to modification during enumeration #539

Description

@Tick-git

Label: Multifaction, Async, Bug

Bug in class: MultiplayerAsyncQuest
System.InvalidOperationException: Collection was modified; enumeration operation may not execute.

Description

An InvalidOperationException is thrown during .TickQuests() because the underlying quest collection is modified during enumeration. This occurs when a quest ends during QuestTick(), triggering a Harmony postfix on Quest.End(). The postfix removes the quest from the cache via TryRemoveCachedQuest, which modifies the list currently being iterated.

Stacktrace.txt

Context

This issue occurred while testing #508. In that PR, ancient exoremains are spawned on maps for each faction. After destroying the remains and defeating the threat from the ship, players can extract a mecha link. Implanting the link triggers a hidden quest. Once the quest finishes, the exception is thrown. (Quest: ..\RimWorld\Data\Biotech\Defs\QuestScriptDefs\Script_StartingMech.xml)

While this was triggered by a specific Biotech quest, it’s likely that similar behavior can occur with other quests that complete during a tick.

Steps to Reproduce

  • Host a multiplayer game with async time, multifaction, and Biotech enabled.
  • (Optional) Use dev tools to give pawns strong gear and high shooting skills.
  • Destroy the ancient exorider remains.
  • Decrypt the mech transponder.
  • Accept the resulting quest.
  • Defeat the threat that arrives via ship.
  • Extract the mecha chip.
  • Implant the chip.
  • After a few ticks, a hidden quest finishes.
  • You receive the reward and the error is thrown

Potential fix

Modify the RemoveQuestFromCacheOnQuestEnd Harmony postfix on Quest.End() so that it adds the quest to a pendingRemovals list instead of removing it immediately. Then, after all quests are ticked in TickQuests, iterate over pendingRemovals and remove them safely.

Metadata

Metadata

Assignees

No one assigned

    Labels

    1.5Fixes or bugs relating to 1.5 (Not Anomaly).asyncBugs or issues only in async time mode.bugSomething isn't working.multifactionBugs or issues only in multifaction mode.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions