Quick answer: SetDestination is asynchronous and can be skipped if called while pathPending is still true or if the target moves only fractionally. Either wait for pathPending to flip false, call ResetPath() before re-issuing, or throttle updates to once every few frames.

Here is how to fix Unity NavMeshAgent paths that refuse to update when you change the destination. The agent walks toward the original target while your code happily calls SetDestination with a new vector every frame. The new path never takes effect. Sometimes the agent stops dead in its tracks. Both symptoms come from the same root cause: SetDestination is not a synchronous teleport — it is a request that the navigation system can defer or drop.

The Symptom

Your enemy AI is chasing the player. The player runs around a corner. You call agent.SetDestination(player.position) every frame, but the agent keeps walking toward the spot where the player was. After a few seconds it stops at the stale destination instead of recalculating.

You log agent.destination and see it update. You log agent.hasPath and it returns true. The path data, however, still corresponds to the old route.

What Causes This

SetDestination called during pathPending. If you issue a new destination while a previous path request is still being calculated, the new request can be queued or dropped depending on Unity version. The agent finishes the original calculation and uses that path.

autoRepath disabled. If agent.autoRepath is false, the agent will not regenerate a path when the existing one becomes invalid (for example, when a moving obstacle blocks it). It also does not refresh when the destination changes by a small amount.

Destination on an unreachable surface. If your new target sits off the NavMesh, SetDestination returns true but the path status becomes PathPartial or PathInvalid. The agent walks to the closest reachable point on the old path instead.

Same-frame thrash. Updating destination every frame with a moving target queues a new repath every frame. The agent never finishes any single calculation cleanly.

The Fix

Step 1: Throttle destination updates. Update only every 0.25 seconds or when the target moves a meaningful distance.

using UnityEngine;
using UnityEngine.AI;

[RequireComponent(typeof(NavMeshAgent))]
public class EnemyChase : MonoBehaviour
{
    [SerializeField] private Transform target;
    [SerializeField] private float repathInterval = 0.25f;
    [SerializeField] private float minRepathDistance = 0.5f;

    private NavMeshAgent agent;
    private Vector3 lastTarget;
    private float nextRepath;

    void Awake() { agent = GetComponent<NavMeshAgent>(); }

    void Update()
    {
        if (Time.time < nextRepath) return;
        if (Vector3.Distance(target.position, lastTarget) < minRepathDistance) return;
        if (agent.pathPending) return;

        agent.SetDestination(target.position);
        lastTarget = target.position;
        nextRepath = Time.time + repathInterval;
    }
}

Step 2: Reset the path before forced redirects. When the player teleports or you switch targets, clear the old path explicitly.

public void ChangeTarget(Transform newTarget)
{
    target = newTarget;
    agent.ResetPath();              // Drop the current path
    agent.SetDestination(target.position);
}

Step 3: Validate the destination is on the NavMesh. Use NavMesh.SamplePosition to snap to the nearest valid point.

if (NavMesh.SamplePosition(target.position, out NavMeshHit hit, 2f, NavMesh.AllAreas))
{
    agent.SetDestination(hit.position);
}
else
{
    Debug.LogWarning("Target is off NavMesh");
}

Step 4: Confirm autoRepath is enabled. Check the inspector or set it explicitly: agent.autoRepath = true; The default is true but third-party scripts sometimes disable it.

Why Throttling Matters

NavMesh pathfinding is not free. Each SetDestination call queues an A* search that can touch hundreds of nodes. Calling it every frame with a moving target means the agent spends more CPU on path recalculation than on actual movement, and the visible result is identical to no movement at all because no plan ever finishes before the next request invalidates it.

“SetDestination is a request, not a teleport. Throttle it, gate it on pathPending, and reset before forced redirects.”

Related Issues

For agents that refuse to start moving at all, see NavMeshAgent Not Moving. For agents stuck on edges, see NavMeshAgent Stuck On Edge.

Throttle. Reset. Sample. The agent does the rest.