diff --git a/doc/changelog.markdown b/doc/changelog.markdown
index 7375d310..c9ea2572 100644
--- a/doc/changelog.markdown
+++ b/doc/changelog.markdown
@@ -3,6 +3,7 @@ Lombok Changelog
### v1.18.47 "Edgy Guinea Pig"
* BUGFIX: `@SneakyThrows` usage on JDK26 no longer results in class files that require `lombok.jar` to be on the runtime classpath (which should not be neccessary). [#4040](https://github.com/projectlombok/lombok/issues/4022).
+* FEATURE: New [config key](https://projectlombok.org/features/configuration) `lombok.checkReturnValueAnnotation` (values: `none`, `lombok`; default: `none`) lets lombok generate `@lombok.CheckReturnValue` on generated methods where the return value should not be ignored, such as `@With` methods and `@Builder.build()`. A future lombok release may flip the default to `lombok`. [#4013](https://github.com/projectlombok/lombok/pull/4013).
* PROMOTION: `@SuperBuilder` has been promoted to the main package. Otherwise, no changes have been made to the annotation. The old experimental annotation will remain for a few versions, at which point it will be marked as a deprecated annotation. Eventually it'll be removed. If you had `lombok.config` configuration for this annotation, the configuration keys for this feature have been renamed.
* OLD-CRUFT: `lombok.experimental.Wither` and `lombok.Delegate` are deprecated remnants; these features were moved (to respectively `lombok.With` and `lombok.experimental.Delegate` over 5 years ago. They are now removed entirely. If your project is dependent on an older version of lombok which still has those; fret not, lombok still processes these annotations. It just no longer includes them in the jar.
diff --git a/src/core/lombok/CheckReturnValue.java b/src/core/lombok/CheckReturnValue.java
index 1a8f2dcb..0f6ae868 100644
--- a/src/core/lombok/CheckReturnValue.java
+++ b/src/core/lombok/CheckReturnValue.java
@@ -35,7 +35,7 @@ import java.lang.annotation.Target;
* Static analysis tools (Error Prone, IntelliJ, SpotBugs) recognize {@code @CheckReturnValue}
* by simple class name, regardless of package, and will warn when the return value is discarded.
*
- * If you want to opt in, you can add {@code lombok.addCheckReturnValueAnnotation = true} to
+ * If you want to opt in, you can add {@code lombok.checkReturnValueAnnotation = lombok} to
* {@code lombok.config}.
*/
@Target({ElementType.METHOD})
diff --git a/src/core/lombok/ConfigurationKeys.java b/src/core/lombok/ConfigurationKeys.java
index 321b1de6..9dafc083 100644
--- a/src/core/lombok/ConfigurationKeys.java
+++ b/src/core/lombok/ConfigurationKeys.java
@@ -25,6 +25,7 @@ import java.util.List;
import lombok.core.configuration.CallSuperType;
import lombok.core.configuration.CapitalizationStrategy;
+import lombok.core.configuration.CheckReturnValueFlavor;
import lombok.core.configuration.CheckerFrameworkVersion;
import lombok.core.configuration.ConfigurationKey;
import lombok.core.configuration.FlagUsageType;
@@ -91,12 +92,13 @@ public class ConfigurationKeys {
public static final ConfigurationKey ADD_LOMBOK_GENERATED_ANNOTATIONS = new ConfigurationKey("lombok.addLombokGeneratedAnnotation", "Generate @lombok.Generated on all generated code (default: true).") {};
/**
- * lombok configuration: {@code lombok.addCheckReturnValueAnnotation} = {@code true} | {@code false}.
+ * lombok configuration: {@code lombok.checkReturnValueAnnotation} = [{@code none} | {@code lombok}].
*
- * If {@code true}, lombok generates {@code @lombok.CheckReturnValue} on generated methods where the return value should not be ignored,
+ * If set to {@code lombok}, lombok generates {@code @lombok.CheckReturnValue} on generated methods where the return value should not be ignored,
* such as {@code @With} methods and {@code @Builder}'s {@code build()} method.
+ * If set to {@code none} (the current default), no such annotation is emitted. A future lombok release may flip the default to {@code lombok}.
*/
- public static final ConfigurationKey ADD_CHECK_RETURN_VALUE_ANNOTATIONS = new ConfigurationKey("lombok.addCheckReturnValueAnnotation", "Generate @lombok.CheckReturnValue on generated methods where the return value should not be ignored (default: false).") {};
+ public static final ConfigurationKey CHECK_RETURN_VALUE_ANNOTATION = new ConfigurationKey("lombok.checkReturnValueAnnotation", "Which @CheckReturnValue annotation flavor to emit on generated methods. Values: none, lombok (default: none).") {};
/**
* lombok configuration: {@code lombok.extern.findbugs.addSuppressFBWarnings} = {@code true} | {@code false}.
diff --git a/src/core/lombok/core/configuration/CheckReturnValueFlavor.java b/src/core/lombok/core/configuration/CheckReturnValueFlavor.java
new file mode 100644
index 00000000..b313ee73
--- /dev/null
+++ b/src/core/lombok/core/configuration/CheckReturnValueFlavor.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2026 The Project Lombok Authors.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+package lombok.core.configuration;
+
+/** Used for lombok configuration to select which {@code @CheckReturnValue} annotation flavor to emit on generated methods. */
+public enum CheckReturnValueFlavor {
+ NONE, LOMBOK;
+}
diff --git a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java
index 8255d1cb..df0bb234 100644
--- a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java
+++ b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java
@@ -116,6 +116,7 @@ import lombok.core.AnnotationValues;
import lombok.core.AnnotationValues.AnnotationValue;
import lombok.core.LombokImmutableList;
import lombok.core.TypeResolver;
+import lombok.core.configuration.CheckReturnValueFlavor;
import lombok.core.configuration.CheckerFrameworkVersion;
import lombok.core.configuration.NullAnnotationLibrary;
import lombok.core.configuration.NullCheckExceptionType;
@@ -2128,8 +2129,15 @@ public class EclipseHandlerUtil {
}
public static Annotation[] addCheckReturnValue(EclipseNode node, ASTNode source, Annotation[] originalAnnotationArray) {
- if (!Boolean.TRUE.equals(node.getAst().readConfiguration(ConfigurationKeys.ADD_CHECK_RETURN_VALUE_ANNOTATIONS))) return originalAnnotationArray;
- return addAnnotation(source, originalAnnotationArray, LOMBOK_CHECK_RETURN_VALUE);
+ CheckReturnValueFlavor flavor = node.getAst().readConfiguration(ConfigurationKeys.CHECK_RETURN_VALUE_ANNOTATION);
+ if (flavor == null) flavor = CheckReturnValueFlavor.NONE;
+ switch (flavor) {
+ case LOMBOK:
+ return addAnnotation(source, originalAnnotationArray, LOMBOK_CHECK_RETURN_VALUE);
+ case NONE:
+ default:
+ return originalAnnotationArray;
+ }
}
static Annotation[] addAnnotation(ASTNode source, Annotation[] originalAnnotationArray, char[][] annotationTypeFqn) {
diff --git a/src/core/lombok/javac/handlers/JavacHandlerUtil.java b/src/core/lombok/javac/handlers/JavacHandlerUtil.java
index 722bb436..0f134b8e 100644
--- a/src/core/lombok/javac/handlers/JavacHandlerUtil.java
+++ b/src/core/lombok/javac/handlers/JavacHandlerUtil.java
@@ -96,6 +96,7 @@ import lombok.core.AnnotationValues.AnnotationValue;
import lombok.core.CleanupTask;
import lombok.core.LombokImmutableList;
import lombok.core.TypeResolver;
+import lombok.core.configuration.CheckReturnValueFlavor;
import lombok.core.configuration.CheckerFrameworkVersion;
import lombok.core.configuration.NullAnnotationLibrary;
import lombok.core.configuration.NullCheckExceptionType;
@@ -1555,8 +1556,16 @@ public class JavacHandlerUtil {
}
public static void addCheckReturnValue(JCModifiers mods, JavacNode node, JavacNode source) {
- if (!Boolean.TRUE.equals(node.getAst().readConfiguration(ConfigurationKeys.ADD_CHECK_RETURN_VALUE_ANNOTATIONS))) return;
- addAnnotation(mods, node, source, "lombok.CheckReturnValue", null);
+ CheckReturnValueFlavor flavor = node.getAst().readConfiguration(ConfigurationKeys.CHECK_RETURN_VALUE_ANNOTATION);
+ if (flavor == null) flavor = CheckReturnValueFlavor.NONE;
+ switch (flavor) {
+ case LOMBOK:
+ addAnnotation(mods, node, source, "lombok.CheckReturnValue", null);
+ return;
+ case NONE:
+ default:
+ return;
+ }
}
public static void addAnnotation(JCModifiers mods, JavacNode node, JavacNode source, String annotationTypeFqn, JCExpression arg) {
diff --git a/test/transform/resource/before/CheckReturnValueBuilder.java b/test/transform/resource/before/CheckReturnValueBuilder.java
index a4a904ee..83c9e551 100644
--- a/test/transform/resource/before/CheckReturnValueBuilder.java
+++ b/test/transform/resource/before/CheckReturnValueBuilder.java
@@ -1,4 +1,4 @@
-//CONF: lombok.addCheckReturnValueAnnotation = true
+//CONF: lombok.checkReturnValueAnnotation = lombok
@lombok.Builder
class CheckReturnValueBuilder {
private final int x;
diff --git a/test/transform/resource/before/CheckReturnValueOff.java b/test/transform/resource/before/CheckReturnValueOff.java
index 3a4aebca..7197fc75 100644
--- a/test/transform/resource/before/CheckReturnValueOff.java
+++ b/test/transform/resource/before/CheckReturnValueOff.java
@@ -1,4 +1,4 @@
-//CONF: lombok.addCheckReturnValueAnnotation = false
+//CONF: lombok.checkReturnValueAnnotation = none
import lombok.With;
class CheckReturnValueOff {
@With final int x;
diff --git a/test/transform/resource/before/CheckReturnValueWith.java b/test/transform/resource/before/CheckReturnValueWith.java
index 167aaae8..6ed0dba9 100644
--- a/test/transform/resource/before/CheckReturnValueWith.java
+++ b/test/transform/resource/before/CheckReturnValueWith.java
@@ -1,4 +1,4 @@
-//CONF: lombok.addCheckReturnValueAnnotation = true
+//CONF: lombok.checkReturnValueAnnotation = lombok
import lombok.With;
class CheckReturnValueWith {
@With final int x;
diff --git a/website/templates/features/configuration.html b/website/templates/features/configuration.html
index 6675d61e..a09b0c81 100644
--- a/website/templates/features/configuration.html
+++ b/website/templates/features/configuration.html
@@ -89,6 +89,12 @@
Many flavors are available: jspecify (recommended), checkerframework (recommended), jakarta, eclipse, jetbrains, netbeans, androidx, findbugs, spring, jml, javax (=JSR305; not recommended), android.support (deprecated within android), or define your own via CUSTOM:fully.qualified.NonNullAnnotation:fully.qualified.NullableAnnotation; if your nullity annotation is solely of the type use style (it annotates types, such as eclipse's and checkerframework's offerings, versus annotating methods and parameters), the format is CUSTOM:TYPE_USE:nonnullanno:nullableanno.
This feature was added in lombok v1.18.12.
+
+ Lombok can add a @CheckReturnValue annotation to generated methods whose return value should not be ignored, such as withX methods and @Builder's build() method. Static analysis tools (IntelliJ, Error Prone, SpotBugs) will then warn when callers discard the result. By default, no such annotation is added. Enable with:
+
+ lombok.checkReturnValueAnnotation = <flavor>
+
+ Currently the only non-none flavor is lombok, which emits @lombok.CheckReturnValue. A future lombok release may flip the default to lombok.
Lombok can be configured to add @lombok.Generated annotations to all generated nodes where possible; useful for JaCoCo (which has built in support),
or other style checkers and code coverage tools: