Skip to content

[KSP2] @ColumnInfo(name=…) argument dropped on override property when a @property:-targeted annotation is also present (regression in 2.3.10) #3047

Description

@r0shka

@ColumnInfo(name = …) argument is dropped on an override property when a @property:-targeted annotation is also present (KSP2, 2.3.10)

Hello! We run into a following issue when trying to bump ksp from 2.3.9 to 2.3.10:

Summary

On KSP2, when a Room @Entity property is an override (from an interface) and carries both:

  1. a Java-first annotation with an argument — @ColumnInfo(name = "map_style"), and
  2. a use-site–targeted Kotlin annotation — @property:MyAnnotation

…KSP no longer surfaces the @ColumnInfo name argument to the Room processor. Room falls back to the Kotlin property name for the column, so the generated schema column is named after the property (syncMapStyle) instead of the declared @ColumnInfo name (map_style).

Removing the @property:-targeted annotation, or making the property non-override, makes the name argument reappear. So the trigger is the combination of override + @ColumnInfo(name=…) + a second @property: annotation on the same declaration.

This is a silent miscompile: no KSP error, no Room warning. The only symptom is a wrong column name in the generated _Impl, which surfaces at runtime as:

java.lang.IllegalStateException: Migration didn't properly handle: Trip(...RoomTrip).
 Expected:
 TableInfo{ ... columns include 'syncMapStyle', 'syncMapViewMode' ... }
 Found:
 TableInfo{ ... columns include 'map_style', 'view_mode' ... }

For any app with an existing on-disk database, this crashes on every upgrade.

Environment

KSP 2.3.10
Kotlin 2.4.0
Room 2.8.4
AGP 9.2.1
KSP mode KSP2

Does not reproduce on KSP 2.3.9 (same Kotlin/Room) — generated column is correctly map_style. This is a regression in 2.3.10.

Reproduction

Minimal entity (full runnable MRE below / attached):

interface HasMapStyle {
    var syncMapStyle: Int?
}

@Entity(tableName = "Trip")
class RoomTrip(
    @PrimaryKey val uuid: String,

    // ✅ resolves to column `end_date` — plain @ColumnInfo(name = …)
    @ColumnInfo(name = "end_date")
    var endDate: Long? = null,

    // ❌ resolves to column `syncMapStyle` (property name) instead of `map_style`
    //    ONLY because a @property: annotation coexists with @ColumnInfo(name = …)
    @ColumnInfo(name = "map_style")
    @property:MyMarker
    override var syncMapStyle: Int? = null,
) : HasMapStyle

@Retention(AnnotationRetention.SOURCE)
annotation class MyMarker

Generated PolarstepsDatabase_Impl CREATE TABLE (KSP 2.3.10):

CREATE TABLE IF NOT EXISTS `Trip` (... `end_date` REAL, `syncMapStyle` INTEGER, ...)
                                                        ^^^^^^^^^^^^  should be `map_style`

Generated _columnsTrip TableInfo entries likewise omit map_style and instead register syncMapStyle.

Expected

@ColumnInfo(name = "map_style") is honored regardless of the presence of an additional @property:-targeted annotation, i.e. the generated column is map_style (as it is on KSP 2.3.9, and as it is when the @property:MyMarker line is deleted).

Metadata

Metadata

Assignees

No one assigned

    Labels

    P3desirablebugSomething isn't workingcoreIssues related to the core implementation of KSP API.

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions