quarkusio/quarkus · error · RuntimeException

Cannot get QueryReader for: " + type

Error message

Cannot get QueryReader for: " + type

What it means

QueryObjectMapper.readerFor(Type) can only produce a QueryReader for plain Class types or parameterized types. Any other Type implementation (GenericArrayType, WildcardType, TypeVariable) is rejected with 'Cannot get QueryReader for: <type>'.

Source

Thrown at extensions/funqy/funqy-server-common/runtime/src/main/java/io/quarkus/funqy/runtime/query/QueryObjectMapper.java:85

            };
        }
        return null;
    }

    Map<Class, QueryObjectReader> readers = new HashMap<>();

    public <T> QueryReader<T> readerFor(Class<T> clz) {
        return readerFor(clz, null);
    }

    public QueryReader readerFor(Type type) {
        Class<?> clazz = null;
        if (type instanceof Class) {
            clazz = (Class<?>) type;
        } else if (type instanceof ParameterizedType) {
            clazz = (Class<?>) ((ParameterizedType) type).getRawType();
        } else {
            throw new RuntimeException("Cannot get QueryReader for: " + type);
        }
        return readerFor(clazz, type);
    }

    public <T> QueryReader<T> readerFor(Class<T> clz, Type genericType) {
        if (clz.equals(Map.class)) {
            return (QueryReader<T>) new QueryMapReader(genericType, this);
        }
        QueryObjectReader reader = readers.get(clz);
        if (reader != null)
            return (QueryReader<T>) reader;
        reader = new QueryObjectReader(clz, this);
        readers.put(clz, reader);
        return (QueryReader<T>) reader;
    }

    QueryPropertySetter setterFor(Class clz, Type genericType) {
        if (clz.equals(List.class)) {

View on GitHub (pinned to e1c734241f)

Solutions

  1. Replace wildcard types with concrete types in the function signature (List<String> instead of List<?>)
  2. Use a concrete class parameter instead of a generic type variable
  3. Unwrap parameterized types manually before calling readerFor if using the mapper API directly

Example fix

// before
@Funq public void f(List<?> items) { ... }
// after
@Funq public void f(List<String> items) { ... }
Defensive patterns

Strategy: type-guard

Validate before calling

// Reject unsupported Type kinds before calling readerFor
static void assertReaderCapable(Type t) {
    if (!(t instanceof Class || t instanceof ParameterizedType))
        throw new IllegalArgumentException("Unsupported type: " + t);
}

Type guard

static boolean isReaderCapable(Type t) {
    return t instanceof Class || t instanceof ParameterizedType;
}

Try / catch

try {
    QueryReader<?> r = mapper.readerFor(type);
} catch (RuntimeException e) {
    if (e.getMessage().startsWith("Cannot get QueryReader for:"))
        log.error("Replace wildcard/type-variable generics with concrete types");
    throw e;
}

Prevention

When it happens

Trigger: A @Funq function parameter whose resolved generic type is a wildcard (List<?>) or type variable (T) reaching query binding resolution.

Common situations: Using wildcard generics in function signatures; generic wrapper classes passed as parameters; frameworks resolving types to TypeVariable due to erased generics.

Related errors


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