Tencent/tinker · error · NoSuchFieldException

Field {} not found in {}

Error message

Field {} not found in {}

What it means

ShareReflectUtil.findField(Object instance, String name) walks instance.getClass() up the superclass chain calling getDeclaredField; if no class in the hierarchy declares the field it throws NoSuchFieldException('Field <name> not found in <instance.getClass()>'). Note the message reports the instance's concrete class, not each class searched. This error means framework internals the code depends on are absent or renamed on this device.

Source

Thrown at tinker-android/tinker-android-loader-no-op/src/main/java/com/tencent/tinker/loader/shareutil/ShareReflectUtil.java:55

     * @return a field object
     * @throws NoSuchFieldException if the field cannot be located
     */
    public static Field findField(Object instance, String name) throws NoSuchFieldException {
        for (Class<?> clazz = instance.getClass(); clazz != null; clazz = clazz.getSuperclass()) {
            try {
                Field field = clazz.getDeclaredField(name);

                if (!field.isAccessible()) {
                    field.setAccessible(true);
                }

                return field;
            } catch (NoSuchFieldException e) {
                // ignore and search next
            }
        }

        throw new NoSuchFieldException("Field " + name + " not found in " + instance.getClass());
    }

    public static Field findField(Class<?> originClazz, String name) throws NoSuchFieldException {
        for (Class<?> clazz = originClazz; clazz != null; clazz = clazz.getSuperclass()) {
            try {
                Field field = clazz.getDeclaredField(name);

                if (!field.isAccessible()) {
                    field.setAccessible(true);
                }

                return field;
            } catch (NoSuchFieldException e) {
                // ignore and search next
            }
        }

        throw new NoSuchFieldException("Field " + name + " not found in " + originClazz);

View on GitHub (pinned to 1b7ea02c23)

Solutions

  1. Identify the field name and target class at the call site and check the AOSP source for the device's Android version to get the correct name.
  2. Upgrade tinker — version-gated reflection tables (V14/V19/V23/... classes) are maintained precisely for this.
  3. Add the missing-field case to a fallback chain: try several known field names before giving up.
  4. If the field belongs to your own classes, fix proguard rules so the name survives obfuscation.

Example fix

// before
Field f = ShareReflectUtil.findField(classLoader, "pathList");

// after
Field f;
try {
    f = ShareReflectUtil.findField(classLoader, "pathList");
} catch (NoSuchFieldException e) {
    throw new IllegalStateException("Unsupported ClassLoader impl: " + classLoader.getClass(), e);
}
Defensive patterns

Strategy: try-catch

Try / catch

try { f = ShareReflectUtil.findField(instance, name); } catch (NoSuchFieldException e) { throw new UnsupportedOperationException('unsupported device framework', e); }

Prevention

When it happens

Trigger: Reflecting over Android framework internals whose name differs per OEM or API level (e.g. PathClassLoader fields across 4.x-13); passing an instance whose runtime class is a subclass/proxy that hides the expected hierarchy; proguard renaming app fields that the lookup expected.

Common situations: New Android releases renaming/repackaging internal ClassLoader members; OEM-skinned frameworks moving fields; security-hardened ROMs; code copied from another tinker version targeting a different field set.

Related errors


AI-assisted analysis of Tencent/tinker@1b7ea02c23 (2026-08-14). Data as JSON: /api/errors/6d11820f568c8cdb. Report an issue: GitHub.