MuntashirAkon/AppManager · error · BadParcelableException

Parcelable protocol requires that the class implements Parce

Error message

Parcelable protocol requires that the class implements Parcelable

What it means

ParcelUtils.readParcelableCreator loads the class named in the Parcel via reflection and, following the Parcelable protocol, requires it to implement android.os.Parcelable before looking up its CREATOR. If the loaded class does not implement Parcelable, a BadParcelableException is thrown.

Source

Thrown at libcore/io/src/main/java/aosp/android/content/pm/ParcelUtils.java:62

        Parcelable.Creator<?> creator;
        synchronized (mCreators) {
            HashMap<String, Parcelable.Creator<?>> map = mCreators.get(loader);
            if (map == null) {
                map = new HashMap<>();
                mCreators.put(loader, map);
            }
            creator = map.get(name);
            if (creator == null) {
                try {
                    // If loader == null, explicitly emulate Class.forName(String) "caller
                    // classloader" behavior.
                    ClassLoader parcelableClassLoader = (loader == null ? from.getClass().getClassLoader() : loader);
                    // Avoid initializing the Parcelable class until we know it implements
                    // Parcelable and has the necessary CREATOR field.
                    Class<?> parcelableClass = Class.forName(name, false /* initialize */,
                            parcelableClassLoader);
                    if (!Parcelable.class.isAssignableFrom(parcelableClass)) {
                        throw new BadParcelableException("Parcelable protocol requires that the "
                                + "class implements Parcelable");
                    }
                    Field f = parcelableClass.getField("CREATOR");
                    if ((f.getModifiers() & Modifier.STATIC) == 0) {
                        throw new BadParcelableException("Parcelable protocol requires "
                                + "the CREATOR object to be static on class " + name);
                    }
                    Class<?> creatorType = f.getType();
                    if (!Parcelable.Creator.class.isAssignableFrom(creatorType)) {
                        // Fail before calling Field.get(), not after, to avoid initializing
                        // parcelableClass unnecessarily.
                        throw new BadParcelableException("Parcelable protocol requires a "
                                + "Parcelable.Creator object called "
                                + "CREATOR on class " + name);
                    }
                    creator = (Parcelable.Creator<?>) f.get(null);
                } catch (IllegalAccessException e) {
                    Log.e(TAG, "Illegal access when unmarshalling: " + name, e);

View on GitHub (pinned to 0152f468fc)

Solutions

  1. Make the named class implement android.os.Parcelable and provide a static CREATOR
  2. Ensure the writer side actually writes a Parcelable class name (check writeParcelable calls)
  3. Clear/regenerate stale parcelized data after refactoring the class
  4. Verify both IPC endpoints use the same class definition (same version)

Example fix

// before
class MyData { String x; }
// after
class MyData implements Parcelable {
    String x;
    public static final Creator<MyData> CREATOR = new Creator<MyData>() { /* ... */ };
}
Defensive patterns

Strategy: try-catch

Validate before calling

try {
    Class<?> c = Class.forName(name, false, loader);
    if (!Parcelable.class.isAssignableFrom(c)) throw new BadParcelableException(name + " not Parcelable");
} catch (ClassNotFoundException e) { /* handle */ }

Type guard

boolean isParcelableClass(String name, ClassLoader loader) {
    try { return Parcelable.class.isAssignableFrom(Class.forName(name, false, loader)); }
    catch (ClassNotFoundException e) { return false; }
}

Try / catch

try {
    T p = ParcelUtils.readParcelable(parcel, loader);
} catch (BadParcelableException e) {
    Log.e(TAG, "Corrupt/incompatible parcel data", e);
}

Prevention

When it happens

Trigger: readParcelable/readParcelableCreator is given a Parcel whose next string is a class name of a type that exists on the classpath but does not implement Parcelable — typically the writer wrote a wrong class name or the class was changed/refactored to no longer implement Parcelable.

Common situations: App upgrade where a formerly-Parcelable class dropped the interface while old parcelized data/IPC traffic still names it; typos in serialized class names; using readParcelable on data written by incompatible code.

Understand the failure class

Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.

Related errors


AI-assisted analysis of MuntashirAkon/AppManager@0152f468fc (2026-09-12). Data as JSON: /api/errors/03717a7ac1e24eac. Report an issue: GitHub.