didi/DoKit · error · UnsupportedOperationException
Could not find char array in {}
Error message
Could not find char array in {} What it means
HahaHelper.asString() decodes a String instance from a parsed heap dump (haha/perflib model). It expects either a direct char[]-backed java.lang.String or (on newer Android versions) a byte[]-backed String with a compact-strings encoding, which it reads reflectively via ArrayInstance.asRawByteArray. If the instance is neither shape, it throws UnsupportedOperationException because it cannot decode the value.
Source
Thrown at Android/dokit-leakcanary/src/main/java/com/squareup/leakcanary/HahaHelper.java:136
// In API 26, Strings are now internally represented as byte arrays.
array = (ArrayInstance) value;
// HACK - remove when HAHA's perflib is updated to https://goo.gl/Oe7ZwO.
try {
Method asRawByteArray =
ArrayInstance.class.getDeclaredMethod("asRawByteArray", int.class, int.class);
asRawByteArray.setAccessible(true);
byte[] rawByteArray = (byte[]) asRawByteArray.invoke(array, 0, count);
return new String(rawByteArray, Charset.forName("UTF-8"));
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
}
} else {
throw new UnsupportedOperationException("Could not find char array in " + instance);
}
}
public static boolean isPrimitiveWrapper(Object value) {
if (!(value instanceof ClassInstance)) {
return false;
}
return WRAPPER_TYPES.contains(((ClassInstance) value).getClassObj().getClassName());
}
public static boolean isPrimitiveOrWrapperArray(Object value) {
if (!(value instanceof ArrayInstance)) {
return false;
}
ArrayInstance arrayInstance = (ArrayInstance) value;
if (arrayInstance.getArrayType() != Type.OBJECT) {
return true;
}View on GitHub (pinned to 626827cddb)
Solutions
- Verify the value is a String instance before decoding: check class name equals 'java.lang.String'
- Upgrade LeakCanary / the haha perflib dependency to a version that supports the heap dump's Android version
- Null-check field values before calling asString (a null 'key' field takes the keysFound.add(null) path instead)
Example fix
// before
String key = HahaHelper.asString(HahaHelper.fieldValue(values, "key"));
// after
Object keyField = HahaHelper.fieldValue(values, "key");
if (keyField == null) { /* record and skip, as HeapAnalyzer does */ }
else {
String key = HahaHelper.asString(keyField);
} Defensive patterns
Strategy: try-catch
Validate before calling
Object v = HahaHelper.fieldValue(values, name);
if (v instanceof Instance && "java.lang.String".equals(((Instance) v).getClassObj().getClassName())) { String s = HahaHelper.asString(v); } Try / catch
try { key = HahaHelper.asString(value); } catch (UnsupportedOperationException e) { // unexpected heap layout: record and skip this instance } Prevention
- Null-check and type-check field values before decoding
- Keep the LeakCanary/haha parser version aligned with the Android versions you capture dumps from
When it happens
Trigger: Calling HahaHelper.asString(instance) where instance is not a java.lang.String ClassInstance from the heap snapshot — e.g. passing a Type, ClassObj, ArrayInstance of the wrong type, or a String whose value field layout does not match what the helper looks for. Happens when heap dumps from newer Android versions (byte-backed strings, ART string layout changes) are parsed by an older haha parser that cannot find the char[] 'value' field.
Common situations: Analyzing a heap dump captured on a recent Android version with an old LeakCanary/haha version bundled in DoraemonKit. Passing KeyedWeakReference field values (e.g. the 'key' field) that resolved to null or a non-string array.
Related errors
- File does not exist: {}
- Could not find the {} class in the heap dump.
- Could not find weak reference with key {} in {}
- leakTraceAsFakeException() can only be called when leakFound
- buildAndInstall() should only be called once.
AI-assisted analysis of didi/DoKit@626827cddb (2026-08-14).
Data as JSON: /api/errors/37445e8d34bf9bf2.
Report an issue: GitHub.