Blankj/AndroidUtilCode · error · IllegalArgumentException
Array has incompatible type: {}
Error message
Array has incompatible type: {} What it means
LogUtils.array2String() converts arrays to string representations for logging. It checks Object[] (via deepToString) and all eight primitive array types. If the object passes none of these instanceof checks, it throws IllegalArgumentException with the class name. In practice this should be unreachable for any real array type, but it fires if a non-array object is passed or in JVM edge cases with custom array-like types.
Source
Thrown at lib/utilcode/src/main/java/com/blankj/utilcode/util/LogUtils.java:1169
return Arrays.deepToString((Object[]) object);
} else if (object instanceof boolean[]) {
return Arrays.toString((boolean[]) object);
} else if (object instanceof byte[]) {
return Arrays.toString((byte[]) object);
} else if (object instanceof char[]) {
return Arrays.toString((char[]) object);
} else if (object instanceof double[]) {
return Arrays.toString((double[]) object);
} else if (object instanceof float[]) {
return Arrays.toString((float[]) object);
} else if (object instanceof int[]) {
return Arrays.toString((int[]) object);
} else if (object instanceof long[]) {
return Arrays.toString((long[]) object);
} else if (object instanceof short[]) {
return Arrays.toString((short[]) object);
}
throw new IllegalArgumentException("Array has incompatible type: " + object.getClass());
}
}
private static <T> Class getTypeClassFromParadigm(final IFormatter<T> formatter) {
Type[] genericInterfaces = formatter.getClass().getGenericInterfaces();
Type type;
if (genericInterfaces.length == 1) {
type = genericInterfaces[0];
} else {
type = formatter.getClass().getGenericSuperclass();
}
type = ((ParameterizedType) type).getActualTypeArguments()[0];
while (type instanceof ParameterizedType) {
type = ((ParameterizedType) type).getRawType();
}
String className = type.toString();
if (className.startsWith("class ")) {
className = className.substring(6);View on GitHub (pinned to 7b4caf9e54)
Solutions
- Convert arrays to a List or to a String before passing to LogUtils: log Arrays.asList(arr) or Arrays.toString(arr) instead.
- Register a custom IFormatter<T> via LogUtils.getConfig().addFormatter() to handle the specific type.
- If hitting this with a standard primitive array, check for class-loader or instrumentation conflicts in your build.
- Wrap the log call in a try-catch for IllegalArgumentException to degrade gracefully.
Example fix
// before
String[] names = {"Alice", "Bob"};
LogUtils.d(names); // triggers array2String internally
// after
String[] names = {"Alice", "Bob"};
LogUtils.d(Arrays.toString(names)); // pre-convert to string Defensive patterns
Strategy: validation
Validate before calling
// Pre-convert arrays to String before logging
Object arg = getLoggableValue();
if (arg != null && arg.getClass().isArray()) {
// Safe: array2String handles Object[] and all primitive arrays
LogUtils.d(arg);
} else {
LogUtils.d(String.valueOf(arg));
} Type guard
static boolean isStandardArrayType(Object obj) {
if (obj == null) return false;
Class<?> componentType = obj.getClass().getComponentType();
if (componentType == null) return false; // not an array
return componentType.isPrimitive()
|| componentType == Object.class
|| componentType == String.class;
} Try / catch
try {
LogUtils.d(myArray);
} catch (IllegalArgumentException e) {
// Fallback: convert manually
LogUtils.d(java.util.Arrays.toString((Object[]) myArray));
} Prevention
- Convert arrays to String with Arrays.toString() or Arrays.asList() before logging.
- Register custom IFormatter<T> for non-standard types via LogUtils.getConfig().addFormatter().
- Wrap log calls in try-catch if logging user-generated or dynamic content.
- Test logging paths with edge-case inputs (nested arrays, empty arrays, Object[] of custom types).
When it happens
Trigger: Internally, LogUtils calls array2String() when it detects the logged object is an array. The error fires if the object is somehow classified as an array by upstream code but doesn't match any known array instanceof check — theoretically impossible for standard JVM array types, but could occur with bytecode manipulation, custom class loaders, or if a non-array slips through a code path that expects an array.
Common situations: Logging a custom type that extends an array-like interface under a modified class loader; instrumentation frameworks that wrap arrays; edge cases in Android Runtime array handling; deserialized array objects that lose their array identity.
Related errors
- u can't instantiate me...
- u can't instantiate me...
- Index: {}, array1 Length: 0
- Index: {}, array1 Length: {}
- Index: {}, Length: 0
AI-assisted analysis of Blankj/AndroidUtilCode@7b4caf9e54 (2026-08-14).
Data as JSON: /api/errors/6ff531ed55c7ef0d.
Report an issue: GitHub.