E201: Non-Named Argument in Java Annotation
This error occurs when using positional (unnamed) arguments in a Java-defined annotation. Starting from Scala 3.6.0, named arguments are required for all Java annotations.
Java annotations don't have an exact constructor representation in Scala, and the compiler previously relied on the order of annotation fields to match positional arguments. This approach is fragile because reordering annotation fields in Java is binary-compatible but can silently change the meaning of positional arguments.
Example
class Foo:
@Deprecated("reason")
def oldMethod(): Unit = ()
Error
-- [E201] Syntax Error: example.scala:2:14 -------------------------------------
2 | @Deprecated("reason")
| ^^^^^^^^
| Named arguments are required for Java defined annotations
| This can be rewritten automatically under -rewrite -source 3.6-migration.
|-----------------------------------------------------------------------------
| Explanation (enabled by `-explain`)
|- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| Starting from Scala 3.6.0, named arguments are required for Java defined annotations.
| Java defined annotations don't have an exact constructor representation
| and we previously relied on the order of the fields to create one.
| One possible issue with this representation is the reordering of the fields.
| Lets take the following example:
|
| public @interface Annotation {
| int a() default 41;
| int b() default 42;
| }
|
| Reordering the fields is binary-compatible but it might affect the meaning of @Annotation(1)
|
-----------------------------------------------------------------------------
Solution
Use named arguments when applying Java annotations:
class Foo:
@Deprecated(since = "reason")
def oldMethod(): Unit = ()
Alternatively, you can use the automatic rewrite feature by compiling with -rewrite -source 3.6-migration to automatically convert positional arguments to named arguments.
In this article