[ksp] java.lang.IllegalArgumentException: List has more than one element.
- 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
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