[Bug][Beta 4.1.16] NullReferenceException:Object reference not set to an instance of an object in Pathfinding.AstarData.AssertSafe

NullReferenceException: Object reference not set to an instance of an object
  at Pathfinding.AstarData.AssertSafe (System.Boolean onlyAddingGraph) [0x0005d] in C:\Users\Kevin Streicher\Documents\repositories\vrame-lfs\VRame\Assets\Plugins\AstarPathfindingProject\Core\AstarData.cs:194 
  at Pathfinding.AstarData.AddGraph (Pathfinding.NavGraph graph) [0x00003] in C:\Users\Kevin Streicher\Documents\repositories\vrame-lfs\VRame\Assets\Plugins\AstarPathfindingProject\Core\AstarData.cs:514 
  at Pathfinding.AstarData.AddGraph (System.Type type) [0x0008e] in C:\Users\Kevin Streicher\Documents\repositories\vrame-lfs\VRame\Assets\Plugins\AstarPathfindingProject\Core\AstarData.cs:506

In a build/dev build this Exception is thrown. As it is not an InvalidOperationException which I’d excpect according to the code, I assume there is something broken.

I am not sure what exactly breaks it yet.

Update

var graphLock = active.PausePathfinding();

Throws and therefore active is not (yet) set when the call to AddGraph happens.

Hi

Can you show me the full stacktrace for this? That doesn’t look like the full stack trace.
Is this something that your code calls?

NullReferenceException: Object reference not set to an instance of an object
  at Pathfinding.AstarData.AssertSafe (System.Boolean onlyAddingGraph) [0x0005d] in C:\Users\Kevin Streicher\Documents\repositories\vrame-lfs\VRame\Assets\Plugins\AstarPathfindingProject\Core\AstarData.cs:194 
  at Pathfinding.AstarData.AddGraph (Pathfinding.NavGraph graph) [0x00003] in C:\Users\Kevin Streicher\Documents\repositories\vrame-lfs\VRame\Assets\Plugins\AstarPathfindingProject\Core\AstarData.cs:514 
  at Pathfinding.AstarData.AddGraph (System.Type type) [0x0008e] in C:\Users\Kevin Streicher\Documents\repositories\vrame-lfs\VRame\Assets\Plugins\AstarPathfindingProject\Core\AstarData.cs:506 
  at Systems.ExitPaths.Graphs.RecastNavigationGraph+ConcreteFactory.Create (Systems.ExitPaths.Graphs.NavigationGraphSettings settings) [0x00031] in C:\Users\Kevin Streicher\Documents\repositories\vrame-lfs\VRame\Assets\Scripts\Systems\ExitPaths\Graphs\RecastNavigationGraph.cs:144 
  at Zenject.FactoryProvider`3+<GetAllInstancesWithInjectSplit>c__Iterator0[TParam1,TValue,TFactory].MoveNext () [0x0013e] in C:\Users\Kevin Streicher\Documents\repositories\vrame-lfs\VRame\Assets\Plugins\Zenject\Source\Providers\FactoryProvider.cs:122 
  at Zenject.IProviderExtensions.GetAllInstances (Zenject.IProvider creator, Zenject.InjectContext context, System.Collections.Generic.List`1[T] args) [0x00011] in C:\Users\Kevin Streicher\Documents\repositories\vrame-lfs\VRame\Assets\Plugins\Zenject\Source\Providers\IProviderExtensions.cs:29 
  at Zenject.IProviderExtensions.GetInstance (Zenject.IProvider creator, Zenject.InjectContext context, System.Collections.Generic.List`1[T] args) [0x00004] in C:\Users\Kevin Streicher\Documents\repositories\vrame-lfs\VRame\Assets\Plugins\Zenject\Source\Providers\IProviderExtensions.cs:75 
  at Zenject.PlaceholderFactory`1[TValue].CreateInternal (System.Collections.Generic.List`1[T] extraArgs) [0x0000f] in C:\Users\Kevin Streicher\Documents\repositories\vrame-lfs\VRame\Assets\Plugins\Zenject\Source\Factories\PlaceholderFactory.cs:32 
Rethrow as ZenjectException: Error during construction of type 'Systems.ExitPaths.Graphs.RecastNavigationGraph' via RecastNavigationGraph.Factory.Create method!
  at Zenject.PlaceholderFactory`1[TValue].CreateInternal (System.Collections.Generic.List`1[T] extraArgs) [0x00068] in C:\Users\Kevin Streicher\Documents\repositories\vrame-lfs\VRame\Assets\Plugins\Zenject\Source\Factories\PlaceholderFactory.cs:40 
  at Zenject.Factory`2[TParam1,TValue].Create (TParam1 param) [0x00015] in C:\Users\Kevin Streicher\Documents\repositories\vrame-lfs\VRame\Assets\Plugins\Zenject\Source\Factories\Factory.cs:38 
  at Systems.ExitPaths.Controller.RecastGraphController+<GetGraphAsync>c__async0.MoveNext () [0x0006b] in C:\Users\Kevin Streicher\Documents\repositories\vrame-lfs\VRame\Assets\Scripts\Systems\ExitPaths\Controller\RecastGraphController.cs:55 
--- End of stack trace from previous location where exception was thrown ---
  at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in <cfc149f8218b496788d8493c87de777a>:0 
  at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x0003e] in <cfc149f8218b496788d8493c87de777a>:0 
  at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x00028] in <cfc149f8218b496788d8493c87de777a>:0 
  at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) [0x00008] in <cfc149f8218b496788d8493c87de777a>:0 
  at System.Runtime.CompilerServices.TaskAwaiter`1[TResult].GetResult () [0x00000] in <cfc149f8218b496788d8493c87de777a>:0 
  at Systems.ExitPaths.Solver+<Solve>c__async0.MoveNext () [0x00080] in C:\Users\Kevin Streicher\Documents\repositories\vrame-lfs\VRame\Assets\Scripts\Systems\ExitPaths\Solver.cs:50 
--- End of stack trace from previous location where exception was thrown ---
  at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in <cfc149f8218b496788d8493c87de777a>:0 
  at System.Runtime.CompilerServices.AsyncMethodBuilderCore+<>c.<ThrowAsync>b__6_0 (System.Object state) [0x00000] in <cfc149f8218b496788d8493c87de777a>:0 
  at UnityEngine.UnitySynchronizationContext+WorkRequest.Invoke () [0x00001] in <2838d14dfe3d46029350279020289155>:0 
  at UnityEngine.UnitySynchronizationContext.Exec () [0x00021] in <2838d14dfe3d46029350279020289155>:0 
  at UnityEngine.UnitySynchronizationContext.ExecuteTasks () [0x00012] in <2838d14dfe3d46029350279020289155>:0 

Called as

public RecastNavigationGraph Create(NavigationGraphSettings settings){
var graph = (RecastGraph) astarPath.Data.AddGraph(typeof(RecastGraph));
return new RecastNavigationGraph(graph);
}

Ok. Then I would guess that you are calling this in Awake before the pathfinding system even has had a chance to start yet. Try to call it in Start instead.

Actually I do call it several frames later. I’ve added some log to the AstarPath.Awake

AWAKE ASTARPATHFINDING PRO (AstarPath:Awake())
A*PP ConfigureReferencesInternal (AstarPath:ConfigureReferencesInternal())
GetGraphAsync>Create

And it only happens in builds. not in the editor

Hm… That’s strange.
Do you know how the ‘astarPath’ variable is set in the code that you linked to above?

It is set by instantiation a prefab and using GetComponent<AstarPath>(). The astarPath variable essentially is a wrapper, which allows me to mock out the dependency to AstarPath for Unit tests

public class AstarPathDecorator
	{
		private readonly AstarPath astarPath;

		public AstarPathDecorator() {}

		[Inject]
		public AstarPathDecorator(AstarPath astarPath) { this.astarPath = astarPath; }

		public virtual IEnumerable<Progress> ScanAsync(NavGraph  graphToScan) => astarPath.ScanAsync(graphToScan);
		public virtual void                  UpdateGraphs(Bounds bounds)      => astarPath.UpdateGraphs(bounds);
		public virtual bool                  IsAnyGraphUpdateInProgress       => astarPath.IsAnyGraphUpdateInProgress;
		public virtual bool                  IsAnyGraphUpdateQueued           => astarPath.IsAnyGraphUpdateQueued;
		public virtual GameObject            GameObject                       => astarPath.gameObject;
		public virtual AstarData             Data                             => astarPath.data;
		public virtual NavGraph[]            Graphs                           => astarPath.graphs;
		public virtual void                  StartPath(Path p)                => AstarPath.StartPath(p);

		public virtual ABPath ABPathConstruct(Vector3 start, Vector3 end, OnPathDelegate callback = null) =>
			ABPath.Construct(start, end, callback);

		public virtual void AssignToGraph(Path p, NavGraph graph) => p.nnConstraint.graphMask = 1 << (int) graph.graphIndex;
	}

It is passed to this constructor marked as inject and is not null at this point. That happens during the inject phase before any awakes, as all other dependency injections. The frame pass, the user clicks on a button and the method is called to create a Graph for the current scene.

It already worked in a build and now I am going back version by version to find the diff. But this is a painful process…

So AstarData.active is just a shortcut to AstarPath.active, and that is only set in the AstarPath.Awake method and then reset in AstarPath.OnDestroy. Can you check if AstarPath.OnDestroy is being called at any point?