Tencent/matrix · error · IllegalStateException

visit string instance failed, lost type def of typeId:

Error message

visit string instance failed, lost type def of typeId: 

What it means

When visiting a String instance in the heap dump, HprofBufferShrinker looks up each field's Type by typeId to locate the `value` field. If the hprof lacks a type definition for a field's typeId, Type.getType returns null and the parser throws IllegalStateException rather than reading stream data with an unknown size, which would desynchronize the whole parse.

Solutions

  1. Re-capture the hprof from the same device/runtime and re-run the shrink/parse.
  2. Upgrade Matrix so its Type/constant tables match the ART version that produced the dump.
  3. Validate the hprof with a standard hprof parser before feeding it to Matrix.
  4. Catch IllegalStateException around parsing and report the dump as unreadable instead of crashing.
Defensive patterns

Strategy: try-catch

Validate before calling

if (hprofFile.length() == 0) {
    throw new IOException("empty hprof: " + hprofFile);
}

Try / catch

try {
    reader.accept(visitor);
} catch (IllegalStateException e) {
    Log.e(TAG, "string instance parse failed", e);
}

Prevention

When it happens

Trigger: Parsing an hprof whose mStringClassInstanceFields contains a Field with an unresolvable typeId — corrupted/truncated dump or a type-id table produced by an incompatible runtime.

Common situations: Hprof captured on an ART version with changed String internals and parsed with an outdated Matrix; truncated hprof files; dumps patched or post-processed by other tools.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


AI-assisted analysis of Tencent/matrix@3b8293bd65 (2026-09-08). Data as JSON: /api/errors/d0823e7819e9a8d9. Report an issue: GitHub.

Appendix: source

Thrown at matrix/matrix-android/matrix-resource-canary/matrix-resource-canary-android/src/main/java/com/tencent/matrix/resource/hproflib/HprofBufferShrinker.java:292

                                } else if (bufferId == null || isRecycled == null) {
                                    IOUtil.skipValue(bais, fieldType, mIdSize);
                                } else {
                                    break;
                                }
                            }
                            bais.close();
                            final boolean reguardAsNotRecycledBmp = (isRecycled == null || !isRecycled);
                            if (bufferId != null && reguardAsNotRecycledBmp && !bufferId.equals(mNullBufferId)) {
                                mBmpBufferIds.add(bufferId);
                            }
                        } else if (mStringClassId != null && mStringClassId.equals(typeId)) {
                            ID strValueId = null;
                            final ByteArrayInputStream bais = new ByteArrayInputStream(instanceData);
                            for (Field field : mStringClassInstanceFields) {
                                final ID fieldNameStringId = field.nameId;
                                final Type fieldType = Type.getType(field.typeId);
                                if (fieldType == null) {
                                    throw new IllegalStateException("visit string instance failed, lost type def of typeId: " + field.typeId);
                                }
                                if (mValueFieldNameStringId.equals(fieldNameStringId)) {
                                    strValueId = (ID) IOUtil.readValue(bais, fieldType, mIdSize);
                                } else if (strValueId == null) {
                                    IOUtil.skipValue(bais, fieldType, mIdSize);
                                } else {
                                    break;
                                }
                            }
                            bais.close();
                            if (strValueId != null && !strValueId.equals(mNullBufferId)) {
                                mStringValueIds.add(strValueId);
                            }
                        }
                    } catch (Throwable thr) {
                        throw new RuntimeException(thr);
                    }
                }

View on GitHub (pinned to 3b8293bd65)