microg/GmsCore · error · IllegalStateException

Can't create Creator for class without constructor

Error message

Can't create Creator for class without constructor

What it means

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.

Source

Thrown at safe-parcel-processor/src/main/kotlin/org/microg/safeparcel/SafeParcelProcessor.kt:132

                    field.isIInterface = true
                } else {
                    error("Field ${field.name} in $fullName has unsupported type ${if (typeName != field.type) "$typeName in ${field.type}" else field.type}.")
                    return false
                }
            }
            val readReflect = field.isPrivate && field.getter == null
            val writeReflect = field.isPrivate && !constructor.fieldIds.contains(field.id)
            when {
                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.")
                writeReflect -> note("Using reflection when writing ${field.name} in $fullName. Consider adding it to the @Constructor for improved performance.")
                readReflect -> note("Using reflection when reading ${field.name} in $fullName. Consider adding a getter to the annotation for improved performance.")
            }
        }
        return true
    }

    fun generateCreator(): String {
        if (constructor == null) throw IllegalStateException("Can't create Creator for class without constructor")
        fun List<String>.linesToString(prefix: String = "") = joinToString("\n                            $prefix")
        val variableDeclarations = fields.map { it.variableDeclaration }.linesToString()
        val setVariablesDefault = fields.map { it.setVariableDefault }.linesToString()
        val readVariablesFromParcel = fields.map { it.readVariableFromParcelCase }.linesToString("        ")
        val writeVariableToParcel = fields.map { it.writeVariableToParcel }.linesToString()
        val setFieldsFromVariables = fields.filter { it.id !in constructor.fieldIds }.flatMap { it.setFieldFromVariable }.linesToString()
        val invokeConstructor = constructor.invocation.linesToString()
        val setVariablesFromFields = fields.flatMap { it.setVariableFromField }.linesToString()
        val file = """
                package $packageName;

                //@javax.annotation.processing.Generated // Not supported by Android
                @androidx.annotation.Keep
                @org.microg.gms.common.Hide
                public class $creatorName implements $SafeParcelableCreatorAndWriter<$fullName> {
                    @Override
                    public $fullName createFromParcel($Parcel parcel) {
                        int end = $SafeParcelReader.readObjectHeader(parcel);

View on GitHub (pinned to 157c9d86ac)

Solutions

  1. Ensure the class declares a constructor whose parameters are annotated with @Field, and the class implements Parcelable.
  2. Do not apply SafeParcel annotations to classes without a parcelable constructor.
  3. Verify kapt/KSP correctly picks up the generated stubs (rebuild; check annotation processor config).
  4. If the class truly has no constructor, generate the Creator manually instead of via the processor.

Example fix

// before
@SafeParcelled
class MyParcel : Parcelable
// after
@SafeParcelled
class MyParcel(@Field(value = 1) val id: Int) : Parcelable
Defensive patterns

Strategy: validation

Validate before calling

// build-time check: ensure the class has a primary constructor with @Field params
if (MyParcel::class.primaryConstructor == null) error("MyParcel needs a @Field-annotated constructor")

Prevention

When it happens

Trigger: 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()`.

Common situations: 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.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of microg/GmsCore@157c9d86ac (2026-09-06). Data as JSON: /api/errors/860d1d714621b4fc. Report an issue: GitHub.