{"record":{"id":"860d1d714621b4fc","repo":"microg/GmsCore","slug":"can-t-create-creator-for-class-without-constructor","errorCode":null,"errorMessage":"Can't create Creator for class without constructor","messagePattern":"Can't create Creator for class without constructor","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"safe-parcel-processor/src/main/kotlin/org/microg/safeparcel/SafeParcelProcessor.kt","lineNumber":132,"sourceCode":"                    field.isIInterface = true\n                } else {\n                    error(\"Field ${field.name} in $fullName has unsupported type ${if (typeName != field.type) \"$typeName in ${field.type}\" else field.type}.\")\n                    return false\n                }\n            }\n            val readReflect = field.isPrivate && field.getter == null\n            val writeReflect = field.isPrivate && !constructor.fieldIds.contains(field.id)\n            when {\n                readReflect && writeReflect -> note(\"Using reflection when accessing ${field.name} in $fullName. Consider adding it to the @Constructor and a getter to the annotation for improved performance.\")\n                writeReflect -> note(\"Using reflection when writing ${field.name} in $fullName. Consider adding it to the @Constructor for improved performance.\")\n                readReflect -> note(\"Using reflection when reading ${field.name} in $fullName. Consider adding a getter to the annotation for improved performance.\")\n            }\n        }\n        return true\n    }\n\n    fun generateCreator(): String {\n        if (constructor == null) throw IllegalStateException(\"Can't create Creator for class without constructor\")\n        fun List<String>.linesToString(prefix: String = \"\") = joinToString(\"\\n                            $prefix\")\n        val variableDeclarations = fields.map { it.variableDeclaration }.linesToString()\n        val setVariablesDefault = fields.map { it.setVariableDefault }.linesToString()\n        val readVariablesFromParcel = fields.map { it.readVariableFromParcelCase }.linesToString(\"        \")\n        val writeVariableToParcel = fields.map { it.writeVariableToParcel }.linesToString()\n        val setFieldsFromVariables = fields.filter { it.id !in constructor.fieldIds }.flatMap { it.setFieldFromVariable }.linesToString()\n        val invokeConstructor = constructor.invocation.linesToString()\n        val setVariablesFromFields = fields.flatMap { it.setVariableFromField }.linesToString()\n        val file = \"\"\"\n                package $packageName;\n\n                //@javax.annotation.processing.Generated // Not supported by Android\n                @androidx.annotation.Keep\n                @org.microg.gms.common.Hide\n                public class $creatorName implements $SafeParcelableCreatorAndWriter<$fullName> {\n                    @Override\n                    public $fullName createFromParcel($Parcel parcel) {\n                        int end = $SafeParcelReader.readObjectHeader(parcel);","sourceCodeStart":114,"sourceCodeEnd":150,"githubUrl":"https://github.com/microg/GmsCore/blob/157c9d86ac46c195a86c2f15ab55c84036223f95/safe-parcel-processor/src/main/kotlin/org/microg/safeparcel/SafeParcelProcessor.kt#L114-L150","documentation":"The safe-parcel annotation processor refuses to generate a Parcelable Creator when the annotated class has no constructor it can use (constructor == null after inspection). SafeParcel generates Creator code that reads constructor fields from the parcel, so a class without a suitable constructor cannot be supported.","triggerScenarios":"Annotating a class with @SafeParcelled (or processing it) where the class defines no primary/secondary constructor matching SafeParcel's expectations — e.g. a synthetic/no-arg-only class, or constructor extraction failed during `process()`.","commonSituations":"Kotlin `object` or class with only default (no-arg) constructor; abstract/interface mistakenly processed; annotation applied to a nested class where kapt sees no explicit constructor; build misconfiguration so the processor inspects the wrong symbol.","solutions":["Ensure the class declares a constructor whose parameters are annotated with @Field, and the class implements Parcelable.","Do not apply SafeParcel annotations to classes without a parcelable constructor.","Verify kapt/KSP correctly picks up the generated stubs (rebuild; check annotation processor config).","If the class truly has no constructor, generate the Creator manually instead of via the processor."],"exampleFix":"// before\n@SafeParcelled\nclass MyParcel : Parcelable\n// after\n@SafeParcelled\nclass MyParcel(@Field(value = 1) val id: Int) : Parcelable","handlingStrategy":"validation","validationCode":"// build-time check: ensure the class has a primary constructor with @Field params\nif (MyParcel::class.primaryConstructor == null) error(\"MyParcel needs a @Field-annotated constructor\")","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always give @SafeParcelled classes an explicit constructor with @Field parameters","Verify kapt/KSP processor configuration on every build","Never annotate abstract classes or objects with SafeParcel annotations"],"tags":["kotlin","annotation-processor","parcelable","compile-time"],"backgroundTag":"missing-required-argument","analyzedSha":"157c9d86ac46c195a86c2f15ab55c84036223f95","analyzedAt":"2026-09-06T17:27:33.892Z","contentChangedAt":"2026-09-06T17:27:33.892Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}