quarkusio/quarkus · error · ClassCastException

Cannot cast <item> of kind <kind> to a io.quarkus.redis.data

Error message

Cannot cast <item> of kind <kind> to a io.quarkus.redis.datasource.graph.GraphQueryResponseItem$RelationItem

What it means

GraphQueryResponseItem results can be SCALAR, NODE, or RELATION. asRelationItem() throws a ClassCastException when called on an item that is not a RELATION (edge), preventing an invalid downcast to RelationItem. Inspect kind() first to select the right accessor.

Source

Thrown at extensions/redis-client/runtime/src/main/java/io/quarkus/redis/datasource/graph/GraphQueryResponseItem.java:35

    default ScalarItem asScalarItem() {
        if (this instanceof ScalarItem) {
            return (ScalarItem) this;
        }
        throw new ClassCastException("Cannot cast " + this + " of kind " + kind() + " to a " + ScalarItem.class.getName());
    }

    default NodeItem asNodeItem() {
        if (this instanceof NodeItem) {
            return (NodeItem) this;
        }
        throw new ClassCastException("Cannot cast " + this + " of kind " + kind() + " to a " + NodeItem.class.getName());
    }

    default RelationItem asRelationItem() {
        if (this instanceof RelationItem) {
            return (RelationItem) this;
        }
        throw new ClassCastException("Cannot cast " + this + " of kind " + kind() + " to a " + RelationItem.class.getName());
    }

    interface ScalarItem extends GraphQueryResponseItem {

        boolean asBoolean();

        int asInteger();

        double asDouble();

        boolean isNull();

        String asString();

        @Override
        default Kind kind() {
            return Kind.SCALAR;
        }

View on GitHub (pinned to e1c734241f)

Solutions

  1. Check item.kind() == Kind.RELATION before calling asRelationItem()
  2. Dispatch on kind() across SCALAR/NODE/RELATION and handle each branch
  3. Update the Cypher query to RETURN the relationship (e.g. r) so the column holds relations
  4. Guard with instanceof RelationItem or try-catch on ClassCastException

Example fix

// before
RelationItem r = row.get(1).asRelationItem();
// after
GraphQueryResponseItem item = row.get(1);
if (item.kind() == GraphQueryResponseItem.Kind.RELATION) {
    RelationItem r = item.asRelationItem();
} else {
    // skip or log non-relation column
}
Defensive patterns

Strategy: type-guard

Validate before calling

if (item.kind() != GraphQueryResponseItem.Kind.RELATION) {
    throw new IllegalStateException("Expected RELATION but got " + item.kind());
}

Type guard

boolean isRelation(GraphQueryResponseItem item) {
    return item instanceof GraphQueryResponseItem.RelationItem;
}

Try / catch

try {
    RelationItem r = item.asRelationItem();
} catch (ClassCastException e) {
    // handle SCALAR/NODE items instead
}

Prevention

When it happens

Trigger: Calling item.asRelationItem() on an item whose kind() is SCALAR or NODE — common when a Cypher query like 'MATCH (a)-[r]->(b) RETURN a, b' returns only nodes and the code assumes an edge column exists.

Common situations: Traversing relationship results but the RETURN clause omits the relationship variable; querying paths that project nodes and scalars only; copy-pasted iteration code that casts everything as relations.

Related errors


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/99ed50c3ae5b4115. Report an issue: GitHub.