Naive implementations of A* can break down in some common scenarios, with highly connected graphs where many solutions exist. Imagine a long barrier with the start and goal placed on either side at the exact midpoint.
Tie handling is really important! A* is often described as minimizing f(n), where f(n) = g(n) + h(n), g(n) = path distance so far, h(n) = distance to goal heuristic. But for any valid shortest path the remaining work for the algorithm to do is determined by the size of g(n). So when selecting the next node to explore you must minimize first by f(n), and then maximize g(n) as a tiebreaker. Same is achieved by breaking ties with LIFO.
Tie handling is really important! A* is often described as minimizing f(n), where f(n) = g(n) + h(n), g(n) = path distance so far, h(n) = distance to goal heuristic. But for any valid shortest path the remaining work for the algorithm to do is determined by the size of g(n). So when selecting the next node to explore you must minimize first by f(n), and then maximize g(n) as a tiebreaker. Same is achieved by breaking ties with LIFO.