{"record":{"id":"db9ff028ec2d9bd5","repo":"microg/GmsCore","slug":"error-writing-s","errorCode":null,"errorMessage":"Error writing %s","messagePattern":"Error writing (.+?)","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"safe-parcel-processor/src/main/kotlin/org/microg/safeparcel/SafeParcelProcessor.kt","lineNumber":184,"sourceCode":"                            $setFieldsFromVariables\n                        } catch (Exception e) {\n                            throw new RuntimeException(String.format(\"Error reading %s\", \"$fullName\"), e);\n                        }\n                        if (parcel.dataPosition() > end) {\n                            throw new RuntimeException(String.format(\"Overread allowed size end=%d\", end));\n                        }\n                        return object;\n                    }\n\n                    @Override\n                    public void writeToParcel($fullName object, $Parcel parcel, int flags) {\n                        int start = $SafeParcelWriter.writeObjectHeader(parcel);\n                        try {\n                            $variableDeclarations\n                            $setVariablesFromFields\n                            $writeVariableToParcel\n                        } catch (Exception e) {\n                            throw new RuntimeException(String.format(\"Error writing %s\", \"$fullName\"), e);\n                        }\n                        $SafeParcelWriter.finishObjectHeader(parcel, start);\n                    }\n\n                    @Override\n                    public $fullName[] newArray(int size) {\n                        return new $fullName[size];\n                    }\n                }\n            \"\"\".trimIndent()\n        return file\n    }\n}\n\nclass ConstructorInfo(val clazz: ClassInfo, val constructorElement: ExecutableElement) {\n    val isPrivate by lazy { constructorElement.modifiers.contains(Modifier.PRIVATE) }\n    val parameters by lazy { constructorElement.parameters }\n    val fieldIds by lazy {","sourceCodeStart":166,"sourceCodeEnd":202,"githubUrl":"https://github.com/microg/GmsCore/blob/157c9d86ac46c195a86c2f15ab55c84036223f95/safe-parcel-processor/src/main/kotlin/org/microg/safeparcel/SafeParcelProcessor.kt#L166-L202","documentation":"SafeParcelProcessor's generated `writeToParcel` wraps variable declaration and field-to-parcel writing in try/catch and rethrows as RuntimeException(\"Error writing <class>\", e). It marks which @SafeParcelable class failed to serialize; the cause reveals the offending field (unsupported type, throwing getter, null that cannot be written, etc.).","triggerScenarios":"Any exception while writing fields of a @SafeParcelable object: a field getter throws, a field value's own writeToParcel fails (nested SafeParcelable/Parcelable with problems), or a field type cannot be represented by SafeParcelWriter.","commonSituations":"Nested Parcelable whose own serialization breaks; lazily-initialized field that is null or throwing at write time; class refactored with a field type the SafeParcel writer cannot handle; transaction stopped mid-write (rare — usually surfaces differently).","solutions":["Read the cause stack trace to identify the failing field","Ensure every @Field has a SafeParcelWriter-supported type and is initialized (non-null or explicitly nullable-safe) before writeToParcel","Fix or remove the nested object that throws during its own writeToParcel","Rebuild the project so generated writer code matches the current class definition"],"exampleFix":"// before: uninitialized field blows up on write\n@Field(value = 2)\nlateinit var config: MyConfig\n// after: write nullable with default\n@Field(value = 2)\nvar config: MyConfig? = null","handlingStrategy":"try-catch","validationCode":"// ensure all fields are initialized before handing the object to a Parcel\nrequire(!requiresInit || ::config.isInitialized) { \"config must be set before parceling\" }","typeGuard":"fun MySafeParcelable.isWritable(): Boolean =\n  this::class.declaredMemberProperties.all { p -> (p.getter.call(this) as? Throwable)?.let { false } ?: true }","tryCatchPattern":"try {\n  dest.writeTypedObject(item, flags)\n} catch (e: RuntimeException) {\n  if (e.message?.startsWith(\"Error writing\") == true) {\n    Log.w(TAG, \"SafeParcel write failed\", e.cause)\n    dest.writeNoOp() // or serialize a fallback representation\n  } else throw e\n}","preventionTips":["Initialize every @Field before the object is parceled; prefer nullable fields over lateinit","Confirm every field type is supported by SafeParcelWriter when adding new fields","Fix nested Parcelables first — a failing child writeToParcel surfaces as this error on the parent"],"tags":["android","parcel","serialization","runtime-exception"],"backgroundTag":"json-marshal-failed","analyzedSha":"157c9d86ac46c195a86c2f15ab55c84036223f95","analyzedAt":"2026-09-06T17:27:33.892Z","contentChangedAt":"2026-09-06T17:27:33.892Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}