google / google/ksp

[ksp] java.lang.IllegalArgumentException: List has more than one element.

Open
#1,700 16 comments 7 reactions 0 assignees View on GitHub
bug incremental P4
Dominant language
Kotlin
Stars
3.5k
Forks
415
Avg merge
1d 2h
Merged PRs (30d)
53

Description

```
> Task :common:kspDevDebugKotlin FAILED
e: [ksp] java.lang.IllegalArgumentException: List has more than one element.
at kotlin.collections.CollectionsKt___CollectionsKt.single(_Collections.kt:610)
at androidx.room.ext.Xelement_extKt.getValueClassUnderlyingProperty(xelement_ext.kt:35)
at androidx.room.solver.TypeAdapterStore.createDefaultTypeAdapter(TypeAdapterStore.kt:383)
at androidx.room.solver.TypeAdapterStore.findColumnTypeAdapter(TypeAdapterStore.kt:368)
at androidx.room.processor.FieldProcessor.process(FieldProcessor.kt:63)
at androidx.room.processor.PojoProcessor.doProcess(PojoProcessor.kt:173)
at androidx.room.processor.PojoProcessor.access$doProcess(PojoProcessor.kt:56)
at androidx.room.processor.PojoProcessor$process$1.invoke(PojoProcessor.kt:112)
at androidx.room.processor.PojoProcessor$process$1.invoke(PojoProcessor.kt:109)
at androidx.room.processor.cache.Cache$Bucket.get(Cache.kt:53)
at androidx.room.processor.PojoProcessor.process(PojoProcessor.kt:109)
at androidx.room.processor.TableEntityProcessor.doProcess(TableEntityProcessor.kt:93)
at androidx.room.processor.TableEntityProcessor.access$doProcess(TableEntityProcessor.kt:44)
at androidx.room.processor.TableEntityProcessor$process$1.invoke(TableEntityProcessor.kt:53)
at androidx.room.processor.TableEntityProcessor$process$1.invoke(TableEntityProcessor.kt:52)
at androidx.room.processor.cache.Cache$Bucket.get(Cache.kt:53)
at androidx.room.processor.TableEntityProcessor.process(TableEntityProcessor.kt:52)
at androidx.room.processor.DatabaseProcessor.processEntities(DatabaseProcessor.kt:468)
at androidx.room.processor.DatabaseProcessor.doProcess(DatabaseProcessor.kt:69)
at androidx.room.processor.DatabaseProcessor.process(DatabaseProcessor.kt:60)
at androidx.room.DatabaseProcessingStep$process$databases$1$1.invoke(DatabaseProcessingStep.kt:68)
at androidx.room.DatabaseProcessingStep$process$databases$1$1.invoke(DatabaseProcessingStep.kt:64)
at androidx.room.processor.Context.collectLogs(Context.kt:192)
at androidx.room.DatabaseProcessingStep.process(DatabaseProcessingStep.kt:64)
at androidx.room.compiler.processing.CommonProcessorDelegate.processRound(XBasicAnnotationProcessor.kt:130)
at androidx.room.compiler.processing.ksp.KspBasicAnnotationProcessor.process(KspBasicAnnotationProcessor.kt:62)
at com.google.devtools.ksp.AbstractKotlinSymbolProcessingExtension$doAnalysis$8$1.invoke(KotlinSymbolProcessingExtension.kt:305)
at com.google.devtools.ksp.AbstractKotlinSymbolProcessingExtension$doAnalysis$8$1.invoke(KotlinSymbolProcessingExtension.kt:303)
at com.google.devtools.ksp.AbstractKotlinSymbolProcessingExtension.handleException(KotlinSymbolProcessingExtension.kt:409)
at com.google.devtools.ksp.AbstractKotlinSymbolProcessingExtension.doAnalysis(KotlinSymbolProcessingExtension.kt:303)
at org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration(TopDownAnalyzerFacadeForJVM.kt:112)
at org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration$default(TopDownAnalyzerFacadeForJVM.kt:88)
at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler$analyze$1.invoke(KotlinToJVMBytecodeCompiler.kt:256)
at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler$analyze$1.invoke(KotlinToJVMBytecodeCompiler.kt:42)
at org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport.analyzeAndReport(AnalyzerWithCompilerReport.kt:115)
at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.analyze(KotlinToJVMBytecodeCompiler.kt:247)
at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.compileModules$cli(KotlinToJVMBytecodeCompiler.kt:87)
at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.compileModules$cli$default(KotlinToJVMBytecodeCompiler.kt:47)
at org.jetbrains.kotlin.cli.jvm.K2JVMCompiler.doExecute(K2JVMCompiler.kt:168)
at org.jetbrains.kotlin.cli.jvm.K2JVMCompiler.doExecute(K2JVMCompiler.kt:53)
at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.kt:100)
at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.kt:46)
at org.jetbrains.kotlin.cli.common.CLITool.exec(CLITool.kt:101)
at org.jetbrains.kotlin.daemon.CompileServiceImpl.compile(CompileServiceImpl.kt:1497)
at jdk.internal.reflect.GeneratedMethodAccessor43.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at java.rmi/sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:360)
at java.rmi/sun.rmi.transport.Transport$1.run(Transport.java:200)
at java.rmi/sun.rmi.transport.Transport$1.run(Transport.java:197)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:712)
at java.rmi/sun.rmi.transport.Transport.serviceCall(Transport.java:196)
at java.rmi/sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:587)
at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:828)
at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:705)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:704)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
at java.base/java.lang.Thread.run(Thread.java:840)

e: Error occurred in KSP, check log for detail

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':common:kspDevDebugKotlin'.

```

Why did this happen? Because we use `value class` which is stored to room.

```
ksp {
arg("room.schemaLocation", "$projectDir/schemas")
arg("room.generateKotlin", "true")
}
```

```kotlin
@Dao
interface RentalDao {

@Query("SELECT * FROM RentalEntity ORDER BY dateFrom ASC")
fun getRentalsFlow(): Flow>

@Query("SELECT * FROM RentalEntity WHERE id = :rentalId LIMIT 1")
fun getRentalFlow(rentalId: String): Flow

@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insert(rental: RentalEntity)

@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertAll(list: List)

@Query("SELECT * FROM RentalEntity WHERE state IN (:queryList)")
fun pagingSource(queryList: List): PagingSource

@Query("DELETE FROM RentalEntity")
suspend fun deleteAll()

@Query("DELETE FROM RentalEntity WHERE state IN (:stateList)")
suspend fun deleteByState(stateList: List)
}
```

```kotlin
@Entity
data class RentalEntity(
@PrimaryKey
val id: String,
val totalAmount: Amount?,
)
```

```kotlin
import android.os.Parcelable
import kotlinx.parcelize.Parcelize
import java.math.BigDecimal

@Parcelize
@JvmInline
value class Amount(
val value: BigDecimal,
) : Parcelable {
companion object {

@Throws(IllegalArgumentException::class)
operator fun invoke(amount: Float?): Amount {
requireNotNull(amount) { "Amount cannot be null!" }
return Amount(amount.toBigDecimal())
}

private const val AMOUNT_MOVE_POINT_BY = 2 // FIXME!!! This line caused this `[ksp] java.lang.IllegalArgumentException: List has more than one element.` crash
}
}
```

versions tested:
```
kotlin = "1.9.10"
room = "2.6.1"
kspPlugin = "1.9.10-1.0.13"
```

and
```
kotlin = "1.9.22"
kspPlugin = "1.9.22-1.0.17"
room = "2.6.1"
```

The `private const val AMOUNT_MOVE_POINT_BY = 2` cause, that KSP failed with a weird error. When line is commented or removed, app/KSP build is a success.

Having another `fun`s in `companion object` is not problem. Only `val` is. `private val AMOUNT_MOVE_POINT_BY = 2` is not OK as well.

Move variable on top (before functions) but still in companion object causes the same problem (so not relevant to ordering).

Contributor guide

Open the contributing guide

Research direction

Start in xelement_ext.kt at getValueClassUnderlyingProperty, then trace the callers in TypeAdapterStore.kt and FieldProcessor.kt shown in the stack trace. Reproduce the failure with the reported value class and companion-object property using :common:kspDevDebugKotlin; done means the valid declaration no longer crashes KSP with IllegalArgumentException.

Written by the indexing model from the issue text.

Assessment

Tech stack
android, kotlin
Domain
compilers, devtools
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.