When parsing `AggregationPath` strings, if we hit an error, we throw `AggregationExecutionException`, which is a 500 class error.  But 500 class errors usually mean that retrying the request might improve the situation, where in this case we want to indicate that the user should not retry with the same request (they need to fix the path expression).  
server/src/main/java/org/elasticsearch/search/aggregations/support/AggregationPath.java
tokens.add(
                        new PathElement(
                            element,
                            element.substring(0, keyIndex),
                            element.substring(keyIndex + 1, element.length() - 1),
                            null
                        )
                    );
                    continue;
                }
                tokens.add(new PathElement(element, element, null, null));
            }
        }
        return new AggregationPath(tokens);
    }
    public record PathElement(String fullName, String name, String key, String metric) {
        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            PathElement token = (PathElement) o;
            return Objects.equals(key, token.key) && Objects.equals(name, token.name) && Objects.equals(metric, token.metric);
        }
        @Override
        public int hashCode() {
            int result = name.hashCode();
            result = 31 * result + (key != null ? key.hashCode() : 0);
            result = 31 * result + (metric != null ? metric.hashCode() : 0);
            return result;
        }