{"record":{"id":"03717a7ac1e24eac","repo":"MuntashirAkon/AppManager","slug":"parcelable-protocol-requires-that-the-class-implements","errorCode":null,"errorMessage":"Parcelable protocol requires that the class implements Parcelable","messagePattern":"Parcelable protocol requires that the class implements Parcelable","errorType":"exception","errorClass":"BadParcelableException","httpStatus":null,"severity":"error","filePath":"libcore/io/src/main/java/aosp/android/content/pm/ParcelUtils.java","lineNumber":62,"sourceCode":"        Parcelable.Creator<?> creator;\n        synchronized (mCreators) {\n            HashMap<String, Parcelable.Creator<?>> map = mCreators.get(loader);\n            if (map == null) {\n                map = new HashMap<>();\n                mCreators.put(loader, map);\n            }\n            creator = map.get(name);\n            if (creator == null) {\n                try {\n                    // If loader == null, explicitly emulate Class.forName(String) \"caller\n                    // classloader\" behavior.\n                    ClassLoader parcelableClassLoader = (loader == null ? from.getClass().getClassLoader() : loader);\n                    // Avoid initializing the Parcelable class until we know it implements\n                    // Parcelable and has the necessary CREATOR field.\n                    Class<?> parcelableClass = Class.forName(name, false /* initialize */,\n                            parcelableClassLoader);\n                    if (!Parcelable.class.isAssignableFrom(parcelableClass)) {\n                        throw new BadParcelableException(\"Parcelable protocol requires that the \"\n                                + \"class implements Parcelable\");\n                    }\n                    Field f = parcelableClass.getField(\"CREATOR\");\n                    if ((f.getModifiers() & Modifier.STATIC) == 0) {\n                        throw new BadParcelableException(\"Parcelable protocol requires \"\n                                + \"the CREATOR object to be static on class \" + name);\n                    }\n                    Class<?> creatorType = f.getType();\n                    if (!Parcelable.Creator.class.isAssignableFrom(creatorType)) {\n                        // Fail before calling Field.get(), not after, to avoid initializing\n                        // parcelableClass unnecessarily.\n                        throw new BadParcelableException(\"Parcelable protocol requires a \"\n                                + \"Parcelable.Creator object called \"\n                                + \"CREATOR on class \" + name);\n                    }\n                    creator = (Parcelable.Creator<?>) f.get(null);\n                } catch (IllegalAccessException e) {\n                    Log.e(TAG, \"Illegal access when unmarshalling: \" + name, e);","sourceCodeStart":44,"sourceCodeEnd":80,"githubUrl":"https://github.com/MuntashirAkon/AppManager/blob/0152f468fc9463ee02dc2ca83f6fe4989a2c4ca5/libcore/io/src/main/java/aosp/android/content/pm/ParcelUtils.java#L44-L80","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Make the named class implement android.os.Parcelable and provide a static CREATOR","Ensure the writer side actually writes a Parcelable class name (check writeParcelable calls)","Clear/regenerate stale parcelized data after refactoring the class","Verify both IPC endpoints use the same class definition (same version)"],"exampleFix":"// before\nclass MyData { String x; }\n// after\nclass MyData implements Parcelable {\n    String x;\n    public static final Creator<MyData> CREATOR = new Creator<MyData>() { /* ... */ };\n}","handlingStrategy":"try-catch","validationCode":"try {\n    Class<?> c = Class.forName(name, false, loader);\n    if (!Parcelable.class.isAssignableFrom(c)) throw new BadParcelableException(name + \" not Parcelable\");\n} catch (ClassNotFoundException e) { /* handle */ }","typeGuard":"boolean isParcelableClass(String name, ClassLoader loader) {\n    try { return Parcelable.class.isAssignableFrom(Class.forName(name, false, loader)); }\n    catch (ClassNotFoundException e) { return false; }\n}","tryCatchPattern":"try {\n    T p = ParcelUtils.readParcelable(parcel, loader);\n} catch (BadParcelableException e) {\n    Log.e(TAG, \"Corrupt/incompatible parcel data\", e);\n}","preventionTips":["Only writeParcelable classes that genuinely implement Parcelable","Keep the Parcelable interface on classes across refactors","Migrate persisted bundles when changing class hierarchies"],"tags":["parcel","android","reflection","serialization"],"backgroundTag":"incompatible-source-type","analyzedSha":"0152f468fc9463ee02dc2ca83f6fe4989a2c4ca5","analyzedAt":"2026-09-12T14:03:37.243Z","contentChangedAt":"2026-09-12T14:03:37.243Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}