[Bug] BehaviorManager - ArgumentOutOfRangeException: Index was out of range.

Lukas

New member
We are getting error reports from built steam game (we send this from game to our internal report system when any error is thrown in unity) that BehaviorManager has gotten error, no idea why or how to reproduce it, since as I said, it did not happen to me, but there are several errors received from built game.

Code:
ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index


System.Collections.Generic.List`1[T].get_Item (System.Int32 index) (at <6aa56e57ab504395b555cf3ed50fa53d>:0)
BehaviorDesigner.Runtime.BehaviorManager.ReevaluateConditionalTasks (BehaviorDesigner.Runtime.BehaviorManager+BehaviorTree behaviorTree) (at <97aa2077f6cf417a80510e3ca36ba81b>:0)
BehaviorDesigner.Runtime.BehaviorManager.Tick (BehaviorDesigner.Runtime.BehaviorManager+BehaviorTree behaviorTree) (at <97aa2077f6cf417a80510e3ca36ba81b>:0)
BehaviorDesigner.Runtime.BehaviorManager.Tick () (at <97aa2077f6cf417a80510e3ca36ba81b>:0)
BehaviorDesigner.Runtime.BehaviorManager.Update () (at <97aa2077f6cf417a80510e3ca36ba81b>:0)

Could we please somehow handle and check if some index out of range could really happen? As it did happen :(

We are using 1.7.4 (as the latest ones did not have any fixes/additions we needed)
 
Can you enable script debugging to be able to determine what line number is causing the issue? I'd like to understand the core issue.
 
The game is in production on steam, so currently its not possible. I can however try to enable script debugging for next build and hope we catch it during that. I am just feat the script debugging may affect the performance a bit.
 
Hello,
I had the same issue. The message appears when the behaviour tree loop on himself. So, you need to avoid that
 
Also, Unity almost crash in fact I m losing the focus and I need to kill unity. it's a big issue in Behavior tree
 
I got the same type of issue on my dev project, here is the state of the call stack
1703789293042.png
the exact error came from the tick loop
1703789351569.png
For a reason, the interruptionTaskStatus is not aligned with activeStack
 
Hi @Justin I've run into this same error on a couple of very complex AI trees after upgrading from v1.6.5 to v1.7.7. One of those trees has not been touched for a very long time so it is 100% caused by the upgrade. I am now running the source version of v1.7.8 in order to figure this out. The bug occurs at the same line CaptNChickN mentioned. The cause is the RestartBehaviorTree task which calls behavior.DisableBehaviour() followed by behavior.EnableBehavior() in OnUpdate() on the same frame. This used to work fine so something has changed internally to break this. Does the task need to be updated? Note that we have other AI trees that also use this task but it does not generate the error. It may be related to the position/number of interrupts in the tree.

Digging into it further, from looking at the stack while in a breakpoint paused state in VSCode it is quite clear that the tree is being restarted mid-tick meaning the interruptionTaskStatus array is changed and so is the activeStack. This causes the breakage. My hack fix is to simply call behavior.EnableBehavior() one frame later. i.e.

C#:
public override TaskStatus OnUpdate()
{
    if (behavior == null) {
        return TaskStatus.Failure;
    }

    // Stop the behavior tree
    behavior.DisableBehavior();
    // Start the behavior tree back up
    // behavior.EnableBehavior();
    StartCoroutine(EnableBehavior()); // Wait a frame in order to allow the stack to be cleaned up in behavior manager
    // Return success
    return TaskStatus.Success;
}

IEnumerator EnableBehavior() {
    yield return null;
    behavior.EnableBehavior();
}

This is the code I added to help me breakpoint on the issue. initialStackCount was 4 but the behaviorTree.activeStack.Count had become 1 mid-loop , similarly the length of interruptionTaskStatus also became 1:

C#:
var initialStackCount = behaviorTree.activeStack.Count;
for (int i = 0; i < initialStackCount; ++i) {
    // ensure there are no interruptions within the hierarchy
    if (i > behaviorTree.interruptionTaskStatus.Count - 1) {
        Debug.Log("BUG");
    }
    TaskStatus status = behaviorTree.interruptionTaskStatus[i];
 
Last edited:
Top