google/gson · error · IllegalArgumentException

Primitive type is not allowed

Error message

Primitive type is not allowed

What it means

Thrown by GsonTypes.checkNotPrimitive(Type) when one of the type arguments supplied to a parameterized type (or a wildcard bound) is a primitive Class such as int.class, boolean.class, or byte.class. The Java Language Specification forbids primitives as type arguments (e.g. List<int> is illegal; you must use List<Integer>), and Gson enforces that same rule when it constructs its internal ParameterizedType / WildcardType implementations.

Source

Thrown at gson/src/main/java/com/google/gson/internal/GsonTypes.java:492

      if (toFind.equals(array[i])) {
        return i;
      }
    }
    throw new NoSuchElementException();
  }

  /**
   * Returns the declaring class of {@code typeVariable}, or {@code null} if it was not declared by
   * a class.
   */
  private static Class<?> declaringClassOf(TypeVariable<?> typeVariable) {
    GenericDeclaration genericDeclaration = typeVariable.getGenericDeclaration();
    return genericDeclaration instanceof Class ? (Class<?>) genericDeclaration : null;
  }

  static void checkNotPrimitive(Type type) {
    if (type instanceof Class<?> && ((Class<?>) type).isPrimitive()) {
      throw new IllegalArgumentException("Primitive type is not allowed");
    }
  }

  /**
   * Whether an {@linkplain ParameterizedType#getOwnerType() owner type} must be specified when
   * constructing a {@link ParameterizedType} for {@code rawType}.
   *
   * <p>Note that this method might not require an owner type for all cases where Java reflection
   * would create parameterized types with owner type.
   */
  public static boolean requiresOwnerType(Type rawType) {
    if (rawType instanceof Class<?>) {
      Class<?> rawTypeAsClass = (Class<?>) rawType;
      return !Modifier.isStatic(rawTypeAsClass.getModifiers())
          && rawTypeAsClass.getDeclaringClass() != null;
    }
    return false;
  }

View on GitHub (pinned to 8b8628c656)

Solutions

  1. Replace the primitive Class with its wrapper: Integer.class, Long.class, Boolean.class, Double.class, etc.
  2. Map primitive classes to wrappers: a helper like Class<?> boxed = Array.get(Array.newInstance(primitive, 0), 0).getClass().
  3. Validate the Type before passing to Gson: if (t instanceof Class && ((Class<?>) t).isPrimitive()) use the wrapper instead.

Example fix

// before
Type t = TypeToken.getParameterized(List.class, int.class).getType();

// after
Type t = TypeToken.getParameterized(List.class, Integer.class).getType();
Defensive patterns

Strategy: validation

Validate before calling

static Type boxIfPrimitive(Type t) {
  if (t instanceof Class<?> c && c.isPrimitive()) {
    // primitive -> wrapper
    return Array.get(Array.newInstance(c, 0), 0).getClass();
  }
  return t;
}
// usage: Type safe = boxIfPrimitive(argType);

Type guard

static boolean isNonPrimitiveType(Type t) {
  return !(t instanceof Class<?> c && c.isPrimitive());
}

Try / catch

try {
  TypeToken.getParameterized(raw, arg).getType();
} catch (IllegalArgumentException e) {
  if (e.getMessage().contains("Primitive type is not allowed")) {
    arg = boxIfPrimitive(arg); // retry with wrapper
  } else throw e;
}

Prevention

When it happens

Trigger: Calling TypeToken.getParameterized(Collection.class, int.class), building a ParameterizedTypeImpl with a primitive in typeArguments, or deserializing into a generic field whose declared type argument resolves to a primitive Class. Also fires for wildcard bounds like ? super int passed to Gson's wildcard construction.

Common situations: Confusing a primitive Class literal (int.class) with its wrapper (Integer.class); auto-boxing assumptions that do not apply to Class objects; reflective code that reads field generic types and forwards primitives; code generation tools emitting primitive type arguments.

Related errors


AI-assisted analysis of google/gson@8b8628c656 (2026-08-04). Data as JSON: /data/errors/9eb0716caa00bdde.json. Report an issue: GitHub.