[Beta 4.1.4] seeker.CancelCurrentPathRequest Exception

Pathfinding Beta 4.1.4
Unity 2017.1.0p4
.Net API 3.5 (Default)

Reproduction Steps

  1. Open Example10_LayeredGridGraph Scene
  2. Change all Bots to ‘Repath Rate’ of 3 seconds
  3. Add ‘SearchPathOnClick’ script:

[code]using Pathfinding;
using UnityEngine;

[RequireComponent(typeof(AIPath))]
[RequireComponent(typeof(Seeker))]
public class SearchPathOnClick : MonoBehaviour {

AIPath aiPath;
Seeker seeker;

private void Awake() {
    aiPath = GetComponent<AIPath>();
    seeker = GetComponent<Seeker>();
}

private void Update() {
    if( Input.GetKeyDown( KeyCode.Mouse0) ) {
        aiPath.SearchPath();
    }

    if( Input.GetKeyDown(KeyCode.Mouse1) ) {
        seeker.CancelCurrentPathRequest();
    }
}

}
[/code]
4. Run Scene
5. Left Click to Search Path, then quickly Right Click to cancel path request (very quickly almost at the same time).

Expected Result
Path seach is canceled, no visual indication.

Actual Result

InvalidOperationException: Would overwrite error log. Do not call FailWithError multiple times. Pathfinding.Path.FailWithError (System.String msg) (at Assets/AstarPathfindingProject/Core/Path.cs:400) Pathfinding.Seeker.CancelCurrentPathRequest (Boolean pool) (at Assets/AstarPathfindingProject/Core/AI/Seeker.cs:141) SearchPathOnClick.Update () (at Assets/AstarPathfindingProject/ExampleScenes/ExampleScripts/SearchPathOnClick.cs:22)

errorLog just contains “Canceled by script (Seeker.CancelCurrentPathRequest)”

This happens in my game when putting an enemy back into an enemy pool, I call Seeker.CancelCurrentPathRequest before putting them back in the pool. I don’t use gameObject.SetActive(false) due to performance problems.

I just commented out the throwing of the exception, seems okay.

I also have another problem that I haven’t been able to create simple reproduction steps for yet.

IndexOutOfRangeException: Array index is out of range. Pathfinding.PathHandler.GetPathNode (Pathfinding.GraphNode node) (at Assets/AstarPathfindingProject/Core/PathHandler.cs:190) Pathfinding.PointNode.Open (Pathfinding.Path path, Pathfinding.PathNode pathNode, Pathfinding.PathHandler handler) (at Assets/AstarPathfindingProject/Generators/NodeClasses/PointNode.cs:128) Pathfinding.ABPath.CalculateStep (Int64 targetTick) (at Assets/AstarPathfindingProject/Pathfinders/ABPath.cs:555) Pathfinding.Path.Pathfinding.IPathInternals.CalculateStep (Int64 targetTick) (at Assets/AstarPathfindingProject/Core/Path.cs:776) Pathfinding.PathProcessor.CalculatePathsThreaded (Pathfinding.PathHandler pathHandler) (at Assets/AstarPathfindingProject/Core/Misc/PathProcessor.cs:329) UnityEngine.Debug:LogException(Exception) Pathfinding.PathProcessor:CalculatePathsThreaded(PathHandler) (at Assets/AstarPathfindingProject/Core/Misc/PathProcessor.cs:383) Pathfinding.<PathProcessor>c__AnonStorey1:<>m__0() (at Assets/AstarPathfindingProject/Core/Misc/PathProcessor.cs:95)

A few other exceptions I get:

ArgumentException: Path must have a length of at least 2 Pathfinding.Util.PathInterpolator.SetPath (System.Collections.Generic.List`1 path) (at Assets/AstarPathfindingProject/Core/Misc/PathInterpolator.cs:81) Pathfinding.AIPath.OnPathComplete (Pathfinding.Path newPath) (at Assets/AstarPathfindingProject/Core/AI/AIPath.cs:188) Pathfinding.Seeker.OnPathComplete (Pathfinding.Path p, Boolean runModifiers, Boolean sendCallbacks) (at Assets/AstarPathfindingProject/Core/AI/Seeker.cs:269) Pathfinding.Seeker.OnPathComplete (Pathfinding.Path path) (at Assets/AstarPathfindingProject/Core/AI/Seeker.cs:237) Pathfinding.Path.ReturnPath () (at Assets/AstarPathfindingProject/Core/Path.cs:717) Pathfinding.Path.Pathfinding.IPathInternals.ReturnPath () (at Assets/AstarPathfindingProject/Core/Path.cs:771) Pathfinding.PathReturnQueue.ReturnPaths (Boolean timeSlice) (at Assets/AstarPathfindingProject/Core/Misc/PathReturnQueue.cs:55) AstarPath.Update () (at Assets/AstarPathfindingProject/Core/AstarPath.cs:770)

ArgumentOutOfRangeException: Argument is out of range. Parameter name: index System.Collections.Generic.List`1[UnityEngine.Vector3].get_Item (Int32 index) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Collections.Generic/List.cs:633) Pathfinding.Util.PathInterpolator.MoveToCircleIntersection2D (Vector3 circleCenter3D, Single radius, IMovementPlane transform) (at Assets/AstarPathfindingProject/Core/Misc/PathInterpolator.cs:170) Pathfinding.AIPath.MovementUpdateInternal (Single deltaTime, UnityEngine.Vector3& nextPosition, UnityEngine.Quaternion& nextRotation) (at Assets/AstarPathfindingProject/Core/AI/AIPath.cs:226) Pathfinding.AIBase.MovementUpdate (Single deltaTime, UnityEngine.Vector3& nextPosition, UnityEngine.Quaternion& nextRotation) (at Assets/AstarPathfindingProject/Core/AI/AIBase.cs:345) Pathfinding.AIBase.FixedUpdate () (at Assets/AstarPathfindingProject/Core/AI/AIBase.cs:337)

I also can sometimes get these 3 in a row:

IndexOutOfRangeException: Array index is out of range. Pathfinding.PathHandler.GetPathNode (Pathfinding.GraphNode node) (at Assets/AstarPathfindingProject/Core/PathHandler.cs:190) Pathfinding.PointNode.Open (Pathfinding.Path path, Pathfinding.PathNode pathNode, Pathfinding.PathHandler handler) (at Assets/AstarPathfindingProject/Generators/NodeClasses/PointNode.cs:128) Pathfinding.ABPath.Initialize () (at Assets/AstarPathfindingProject/Pathfinders/ABPath.cs:423) Pathfinding.Path.Pathfinding.IPathInternals.Initialize () (at Assets/AstarPathfindingProject/Core/Path.cs:775) Pathfinding.PathProcessor.CalculatePathsThreaded (Pathfinding.PathHandler pathHandler) (at Assets/AstarPathfindingProject/Core/Misc/PathProcessor.cs:319) UnityEngine.Debug:LogException(Exception) Pathfinding.PathProcessor:CalculatePathsThreaded(PathHandler) (at Assets/AstarPathfindingProject/Core/Misc/PathProcessor.cs:383) Pathfinding.<PathProcessor>c__AnonStorey1:<>m__0() (at Assets/AstarPathfindingProject/Core/Misc/PathProcessor.cs:95)
Followed by:

Unhandled exception during pathfinding. Terminating. UnityEngine.Debug:LogError(Object) Pathfinding.PathProcessor:CalculatePathsThreaded(PathHandler) (at Assets/AstarPathfindingProject/Core/Misc/PathProcessor.cs:384) Pathfinding.<PathProcessor>c__AnonStorey1:<>m__0() (at Assets/AstarPathfindingProject/Core/Misc/PathProcessor.cs:95)
And then:

Error : This part should never be reached. UnityEngine.Debug:LogError(Object) Pathfinding.PathProcessor:CalculatePathsThreaded(PathHandler) (at Assets/AstarPathfindingProject/Core/Misc/PathProcessor.cs:390) Pathfinding.<PathProcessor>c__AnonStorey1:<>m__0() (at Assets/AstarPathfindingProject/Core/Misc/PathProcessor.cs:95)

This could be me doing something strange though since I can’t reproduce it on the example scenes yet. I think it is related to “Couldn’t find a node close to the end point” sometimes?

I changed AIPath:OnPathComplete from:

if (p == null) throw new System.Exception("This function only handles ABPaths, do not use special path types");

to:

if (p == null || p.vectorPath == null || p.vectorPath.Count < 2 ) throw new System.Exception("This function only handles ABPaths, do not use special path types");

I’m not sure exactly how I get it into that state though, I do create & destroy multiple NavGraphs at runtime.

If I can find simpler repro steps I’ll post them.

I think the 2nd issue is related to NodeLink2. When I remove them I don’t get any errors.

I connect 2 LayeredGridGraphs with a NodeLink2:

Zoomed In

Zoomed Out

I load & remove chunks at runtime to create a very long world world. I’ve seen recommendations to use a single Layered Grid Graph and just move it to follow the player. But this way seems more CPU efficient (less scanning) and works most of the time.

Yeah, that was a stupid bug. I also found it a few days ago but the fix hasn’t made it into the beta yet.

If it is possible for you to get some kind of reproducible test case I would be happy to take a look at it. It looks like a serious issue.

I was able to find some NodeLink2 error reproduction steps:

Reproduction Steps

  1. Open Example10_LayeredGridGraph Scene
  2. Change the existing Layered Grid Graph Width from 200 to 100
  3. Change the existing Layered Grid Graph Center from (0,0,0) to (-25,0,0)
  4. Add a NodeLink2 at (-2,0,6) with an End Node at (2,0,6)
  5. Press Scan on A*
    Expected Setup Image:
  6. Press Play on Unity Editor

Expected Result
The bots will walk around following your cursor and ignore the NodeLink2 since it doesn’t have a valid end yet.

Actual Result
If you lure the bots to the NodeLink2 it will throw the following errors:

ArgumentException: Path must have a length of at least 2 Pathfinding.Util.PathInterpolator.SetPath (System.Collections.Generic.List`1 path) (at Assets/AstarPathfindingProject/Core/Misc/PathInterpolator.cs:81) Pathfinding.AIPath.OnPathComplete (Pathfinding.Path newPath) (at Assets/AstarPathfindingProject/Core/AI/AIPath.cs:187) Pathfinding.Seeker.OnPathComplete (Pathfinding.Path p, Boolean runModifiers, Boolean sendCallbacks) (at Assets/AstarPathfindingProject/Core/AI/Seeker.cs:269) Pathfinding.Seeker.OnPathComplete (Pathfinding.Path path) (at Assets/AstarPathfindingProject/Core/AI/Seeker.cs:237) Pathfinding.Path.ReturnPath () (at Assets/AstarPathfindingProject/Core/Path.cs:713) Pathfinding.Path.Pathfinding.IPathInternals.ReturnPath () (at Assets/AstarPathfindingProject/Core/Path.cs:767) Pathfinding.PathReturnQueue.ReturnPaths (Boolean timeSlice) (at Assets/AstarPathfindingProject/Core/Misc/PathReturnQueue.cs:55) AstarPath.Update () (at Assets/AstarPathfindingProject/Core/AstarPath.cs:770)

ArgumentOutOfRangeException: Argument is out of range. Parameter name: index System.Collections.Generic.List`1[UnityEngine.Vector3].get_Item (Int32 index) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Collections.Generic/List.cs:633) Pathfinding.Util.PathInterpolator.MoveToCircleIntersection2D (Vector3 circleCenter3D, Single radius, IMovementPlane transform) (at Assets/AstarPathfindingProject/Core/Misc/PathInterpolator.cs:170) Pathfinding.AIPath.MovementUpdateInternal (Single deltaTime, UnityEngine.Vector3& nextPosition, UnityEngine.Quaternion& nextRotation) (at Assets/AstarPathfindingProject/Core/AI/AIPath.cs:225) Pathfinding.AIBase.MovementUpdate (Single deltaTime, UnityEngine.Vector3& nextPosition, UnityEngine.Quaternion& nextRotation) (at Assets/AstarPathfindingProject/Core/AI/AIBase.cs:345) Pathfinding.AIBase.Update () (at Assets/AstarPathfindingProject/Core/AI/AIBase.cs:325) Pathfinding.Examples.MineBotAI.Update () (at Assets/AstarPathfindingProject/ExampleScenes/ExampleScripts/MineBotAI.cs:70)

This simulates the case where you are dynamically creating NavGraphs connected by a NodeLink2 but the 2nd nav graph isn’t created yet.

I think a workaround could be to disable the NodeLink2 objects if you know that one of the NavGraphs that it connects to isn’t ready yet. But it would be really cool if NodeLink2 could just handle this situation.

Hi

I manged to replicate it and fix it!
I have uploaded beta 4.1.5 now which includes this fix.

1 Like

The fix works great! :slight_smile:

I took it a bit further and found a few more issues I can reproduce.

The setup takes a bit, so I emailed you a zip of the scene, but it looks like this:

And it has a script that allows you to toggle the NavGraphs On/Off at runtime called LayerGridGraphToggle

It is 2 LayeredGridGraphs connected by NodeLink2s. The problems come from Pressing 1 & 2 to Toggle the Grid Graphs On/Off.

Issue 1 - Cancel & Restart Scan

Reproduction Steps

  1. Open Scene Example10_AtRuntime_NodeLink2
  2. Press Play
  3. Keep the bots on the Left NavGraph
  4. Tap ‘2’ 3 times in a row

Expected Result
Right NavGraph eventually refreshes itself.

Actual Result
Right NavGraph does eventually refresh itself, but there is an exception (seems harmless but probably shouldn’t happen).

Exception: No active AstarPath object to bind to Pathfinding.GraphNode..ctor (.AstarPath astar) (at Assets/AstarPathfindingProject/Core/Nodes/GraphNode.cs:77) Pathfinding.GridNodeBase..ctor (.AstarPath astar) (at Assets/AstarPathfindingProject/Generators/NodeClasses/GridNodeBase.cs:7) Pathfinding.LevelGridNode..ctor (.AstarPath astar) (at Assets/AstarPathfindingProject/Generators/LayerGridGraphGenerator.cs:944) Pathfinding.LayerGridGraph.RecalculateCell (Int32 x, Int32 z, Boolean resetPenalties, Boolean resetTags) (at Assets/AstarPathfindingProject/Generators/LayerGridGraphGenerator.cs:546) Pathfinding.LayerGridGraph+<ScanInternal>c__Iterator0.MoveNext () (at Assets/AstarPathfindingProject/Generators/LayerGridGraphGenerator.cs:412) AstarPath+<ScanGraph>c__Iterator3.MoveNext () (at Assets/AstarPathfindingProject/Core/AstarPath.cs:1575) AstarPath+<ScanAsync>c__Iterator2.MoveNext () (at Assets/AstarPathfindingProject/Core/AstarPath.cs:1514)

Issue 2 - Remove NavGraph with Pathfinders on it

Reproduction Steps

  1. Open Scene Example10_AtRuntime_NodeLink2
  2. Press Play
  3. Keep the bots on the Left NavGraph
  4. Tap ‘1’ two times

Expected Result
Left NavGraph is removed then recalculates. Pathfinders continue on as normal.

Actual Result
Left NavGraph is removed, then the A* System throws the following 3 errors:

IndexOutOfRangeException: Array index is out of range. Pathfinding.PathHandler.GetPathNode (Pathfinding.GraphNode node) (at Assets/AstarPathfindingProject/Core/PathHandler.cs:190) Pathfinding.PointNode.Open (Pathfinding.Path path, Pathfinding.PathNode pathNode, Pathfinding.PathHandler handler) (at Assets/AstarPathfindingProject/Generators/NodeClasses/PointNode.cs:128) Pathfinding.ABPath.Initialize () (at Assets/AstarPathfindingProject/Pathfinders/ABPath.cs:423) Pathfinding.Path.Pathfinding.IPathInternals.Initialize () (at Assets/AstarPathfindingProject/Core/Path.cs:786) Pathfinding.PathProcessor.CalculatePathsThreaded (Pathfinding.PathHandler pathHandler) (at Assets/AstarPathfindingProject/Core/Misc/PathProcessor.cs:319) UnityEngine.Debug:LogException(Exception) Pathfinding.PathProcessor:CalculatePathsThreaded(PathHandler) (at Assets/AstarPathfindingProject/Core/Misc/PathProcessor.cs:383) Pathfinding.<PathProcessor>c__AnonStorey1:<>m__0() (at Assets/AstarPathfindingProject/Core/Misc/PathProcessor.cs:95)

Unhandled exception during pathfinding. Terminating. UnityEngine.Debug:LogError(Object) Pathfinding.PathProcessor:CalculatePathsThreaded(PathHandler) (at Assets/AstarPathfindingProject/Core/Misc/PathProcessor.cs:384) Pathfinding.<PathProcessor>c__AnonStorey1:<>m__0() (at Assets/AstarPathfindingProject/Core/Misc/PathProcessor.cs:95)

Error : This part should never be reached. UnityEngine.Debug:LogError(Object) Pathfinding.PathProcessor:CalculatePathsThreaded(PathHandler) (at Assets/AstarPathfindingProject/Core/Misc/PathProcessor.cs:390) Pathfinding.<PathProcessor>c__AnonStorey1:<>m__0() (at Assets/AstarPathfindingProject/Core/Misc/PathProcessor.cs:95)

Each Pathfinder throws the following error:

NullReferenceException: Object reference not set to an instance of an object Pathfinding.LevelGridNode.GetPortal (Pathfinding.GraphNode other, System.Collections.Generic.List`1 left, System.Collections.Generic.List`1 right, Boolean backwards) (at Assets/AstarPathfindingProject/Generators/LayerGridGraphGenerator.cs:1143) Pathfinding.Funnel.ConstructFunnelPortals (System.Collections.Generic.List`1 nodes, PathPart part) (at Assets/AstarPathfindingProject/Utilities/Funnel.cs:127) Pathfinding.FunnelModifier.Apply (Pathfinding.Path p) (at Assets/AstarPathfindingProject/Modifiers/FunnelModifier.cs:79) Pathfinding.Seeker.RunModifiers (ModifierPass pass, Pathfinding.Path path) (at Assets/AstarPathfindingProject/Core/AI/Seeker.cs:215) Pathfinding.Seeker.OnPathComplete (Pathfinding.Path p, Boolean runModifiers, Boolean sendCallbacks) (at Assets/AstarPathfindingProject/Core/AI/Seeker.cs:253) Pathfinding.Seeker.OnPathComplete (Pathfinding.Path path) (at Assets/AstarPathfindingProject/Core/AI/Seeker.cs:237) Pathfinding.Path.ReturnPath () (at Assets/AstarPathfindingProject/Core/Path.cs:728) Pathfinding.Path.Pathfinding.IPathInternals.ReturnPath () (at Assets/AstarPathfindingProject/Core/Path.cs:782) Pathfinding.PathReturnQueue.ReturnPaths (Boolean timeSlice) (at Assets/AstarPathfindingProject/Core/Misc/PathReturnQueue.cs:55) AstarPath.Update () (at Assets/AstarPathfindingProject/Core/AstarPath.cs:770)

Hi

Wow. You found like, at least 4 bugs there.

  • When adding new graphs, the code did not validate that it was safe to do so.
  • When destroying graphs, the code did not validate that it was safe to do so (this meant that your code could sometimes remove a graph that was currently being scanned, which caused some bad things to happen)
  • When destroying a grid graph, it did not clear connections from nodes in other graphs to the nodes in the grid graph. This could lead to the nodes created by the node link script to still have references to destroyed nodes which could cause the “IndexOutOfRangeException”.
  • When destroying a graph, paths that were already calculated, but had not yet been returned to the Seeker component were just left in the queue so when they were eventually sent to the Seeker they could reference nodes from a graph that did no longer exist.

At least now it doesn’t throw any exceptions anymore except in some cases where your code tries to do things that are not allowed (for example removing a graph while it is being scanned, this will log an exception saying that you cannot do that).

1 Like

I just uploaded beta version 4.1.6 which includes these fixes. Let me know if everything works or if some things are still broken.

Also. I know you probably just did this to test things, but if you just want to recalculate a graph you don’t have to remove it and then add a new one. You can just scan the already existing one.

1 Like

We’ve been testing with beta 4.1.6 all day and it feels very stable!

Thanks so much! :slight_smile:

1 Like