Skip to content

shortestPath(..., {'direction':'BOTH','edge':true}) fails with ClassCastException on empty edge direction #4645

Description

@TobiasJoseHermann

ArcadeDB Version:

26.7.1-SNAPSHOT

Local source checked at:

898aebe60 feat: [#4466] structured JSON logging + per-request correlation IDs (#4639)

OS and JDK Version:

openjdk version "21.0.11" 2026-04-21
OpenJDK Runtime Environment (build 21.0.11+10-1-25.10.2-Ubuntu)
OpenJDK 64-Bit Server VM (build 21.0.11+10-1-25.10.2-Ubuntu, mixed mode, sharing)

Expected behavior

shortestPath(..., {'direction':'BOTH','edge':true}) should return the shortest path including edge RIDs, or an empty path if no path exists.

It should not throw an internal ClassCastException when one of the two directions has no edges.

For the repro below, the expected result is a path containing the source vertex, the edge, and the destination vertex.

Actual behavior

The query fails with:

java.lang.ClassCastException: class java.util.Collections$EmptyIterator cannot be cast to class com.arcadedb.graph.EdgeIterator

Full remote error observed from ArcadeDB Console:

com.arcadedb.remote.RemoteException: Error on executing remote operation SELECT shortestPath((SELECT FROM BugSP_V WHERE name = 'a'), (SELECT FROM BugSP_V WHERE name = 'b'), {'direction':'BOTH','edge':true}) AS path (cause:java.lang.ClassCastException detail:class java.util.Collections$EmptyIterator cannot be cast to class com.arcadedb.graph.EdgeIterator (java.util.Collections$EmptyIterator is in module java.base of loader 'bootstrap'; com.arcadedb.graph.EdgeIterator is in unnamed module of loader 'app'))

Steps to reproduce

CREATE VERTEX TYPE BugSP_V;
CREATE EDGE TYPE BugSP_E;

CREATE VERTEX BugSP_V SET name = 'a';
CREATE VERTEX BugSP_V SET name = 'b';

CREATE EDGE BugSP_E
FROM (SELECT FROM BugSP_V WHERE name = 'a')
TO (SELECT FROM BugSP_V WHERE name = 'b');

SELECT shortestPath(
  (SELECT FROM BugSP_V WHERE name = 'a'),
  (SELECT FROM BugSP_V WHERE name = 'b'),
  {'direction':'BOTH','edge':true}
) AS path;

Source-level notes

This looks like an internal iterator-type mismatch in the edge:true branch.

SQLFunctionShortestPath explicitly supports the edge option:

private static final Set<String> OPTIONS = Set.of("direction", "edgeType", "edgeTypeNames", "maxDepth",
    "edge");

When edge:true is enabled, SQLFunctionShortestPath#getVerticesAndEdges() wraps srcVertex.getEdges(...) with EdgeToVertexIterable:

final Iterable<Edge> edges1 = srcVertex.getEdges(direction, types);
final Iterable<Edge> edges2 = srcVertex.getEdges(direction, types);
return new Pair<>(new EdgeToVertexIterable(edges1, direction), edges2);

EdgeToVertexIterable#iterator() always casts the iterator to EdgeIterator:

return new EdgeToVertexIterator((EdgeIterator) edges.iterator(), direction);

But GraphEngine.EMPTY_EDGE_LIST.iterator() returns Collections.emptyIterator():

public Iterator<Edge> iterator() {
  return Collections.emptyIterator();
}

In direction:BOTH, SQLFunctionShortestPath#getVerticesAndEdges() calls both OUT and IN. For a vertex that has only an outgoing edge, the IN side is empty, so srcVertex.getEdges(Vertex.DIRECTION.IN, ...) can return GraphEngine.EMPTY_EDGE_LIST. Then EdgeToVertexIterable tries to cast that Collections.emptyIterator() to EdgeIterator, causing the ClassCastException.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions