quarkusio/quarkus · error · IllegalArgumentException

Unknown primitive type:

Error message

Unknown primitive type: 

What it means

AsmUtil.unboxIfRequired emits the correct unboxing call for a Jandex primitive Type (e.g. Integer.intValue). If the type is a primitive not handled by the switch (VOID), it throws IllegalArgumentException("Unknown primitive type: ...").

Source

Thrown at core/deployment/src/main/java/io/quarkus/deployment/util/AsmUtil.java:325

                    unbox(mv, "java/lang/Character", "charValue", "C");
                    break;
                case DOUBLE:
                    unbox(mv, "java/lang/Double", "doubleValue", "D");
                    break;
                case FLOAT:
                    unbox(mv, "java/lang/Float", "floatValue", "F");
                    break;
                case INT:
                    unbox(mv, "java/lang/Integer", "intValue", "I");
                    break;
                case LONG:
                    unbox(mv, "java/lang/Long", "longValue", "J");
                    break;
                case SHORT:
                    unbox(mv, "java/lang/Short", "shortValue", "S");
                    break;
                default:
                    throw new IllegalArgumentException("Unknown primitive type: " + jandexType);
            }
        }
    }

    /**
     * Calls the right unboxing method for the given Jandex Type if it is a primitive.
     *
     * @param mv The MethodVisitor on which to visit the unboxing instructions
     * @param type The Jandex Type to unbox if it is a primitive.
     */
    public static void unboxIfRequired(MethodVisitor mv, org.objectweb.asm.Type type) {
        if (type.getSort() <= org.objectweb.asm.Type.DOUBLE) {
            switch (type.getSort()) {
                case org.objectweb.asm.Type.BOOLEAN:
                    unbox(mv, "java/lang/Boolean", "booleanValue", "Z");
                    break;
                case org.objectweb.asm.Type.BYTE:
                    unbox(mv, "java/lang/Byte", "byteValue", "B");

View on GitHub (pinned to e1c734241f)

Solutions

  1. Skip the unboxing call when the Jandex Type is VOID — void values cannot be unboxed
  2. Guard with type.kind() == Kind.PRIMITIVE && primitive() != VOID before calling
  3. If boxing/unboxing a wrapper, pass the wrapper ClassType rather than the primitive VOID type

Example fix

// before
AsmUtil.unboxIfRequired(mv, returnType);
// after
if (!isVoid(returnType)) {
    AsmUtil.unboxIfRequired(mv, returnType);
}
// where isVoid checks kind==PRIMITIVE && primitive()==VOID
Defensive patterns

Strategy: type-guard

Validate before calling

static boolean isUnboxable(org.jboss.jandex.Type t) {
    return t.kind() == org.jboss.jandex.Type.Kind.PRIMITIVE
        && t.asPrimitiveType().primitive() != org.jboss.jandex.Primitive.VOID;
}

Type guard

if (type.kind() == Type.Kind.PRIMITIVE && type.asPrimitiveType().primitive() != Primitive.VOID) {
    AsmUtil.unboxIfRequired(mv, type);
}

Try / catch

try {
    AsmUtil.unboxIfRequired(mv, type);
} catch (IllegalArgumentException e) {
    // skip unboxing for non-value primitives such as void
}

Prevention

When it happens

Trigger: Calling AsmUtil.unboxIfRequired(MethodVisitor, Type) with a Jandex Type of Kind.PRIMITIVE whose primitive() is VOID, e.g. unboxing a method's void return value.

Common situations: Bytecode generators in extensions that route every method return or annotation value through unboxIfRequired without skipping void methods; misparsed descriptors marking VOID as a value type.

Related errors


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