#21578·checkstyle

False Negative: LambdaParameterName silently passes lambdas in switch rule

Author: lithops-ztyCreated Sep 14, 2026Updated Sep 19, 2026
Labelsapproved

I have read check documentation: https://checkstyle.org/checks/naming/lambdaparametername.html I have downloaded the latest checkstyle from: https://checkstyle.org/cmdline.html#Download_and_Run I have executed the cli and showed it below, as cli describes the problem better than 1,000 words

bash
/var/tmp $ javac RuleValueLambda.java
/var/tmp $ cat config.xml
<?xml version="1.0"?>
<!DOCTYPE module PUBLIC
          "-//Checkstyle//DTD Checkstyle Configuration 1.3//EN"
          "https://checkstyle.org/dtds/configuration_1_3.dtd">
<module name="Checker">
  <module name="TreeWalker">
    <module name="LambdaParameterName"/>
  </module>
</module>

/var/tmp $ cat RuleValueLambda.java
import java.util.function.Function;

public class RuleValueLambda {
    Function<String, String> atRuleValue(int x) {
        return switch (x) {
            case 1 -> Word -> Word.trim();      // should be flagged, but is NOT
            default -> w -> w.trim();
        };
    }

    Function<String, String> outsideSwitchRule = Word -> Word.trim();  // flagged
}

/var/tmp $ RUN_LOCALE="-Duser.language=en -Duser.country=US"
/var/tmp $ java $RUN_LOCALE -jar checkstyle-14.1.0-all.jar -c config.xml RuleValueLambda.java
Starting audit..
[ERROR] /var/tmp/RuleValueLambda.java:11:50: Name 'Word' must match pattern '^([a-z][a-zA-Z0-9]*|_)$'. [LambdaParameterName]
Audit done.
Checkstyle ends with 1 errors.

Describe what you expect in detail.

Lambdas as the branch value of switch rules should be checked but are not.


There are two types of LAMBDA nodes in AST:

  1. 'real' -> that defines a lambda, e.g. (a, b) -> a + b
  2. 'fake' -> in a switch rule, e.g. switch(a) { case 1 -> b;}

Checks targeting lambdas should filter out the second type when checking LAMBDA nodes. However, the most obvious filtering logic is erroneous: Wrong

java
final boolean isRealLambda = lambda.getParent().getType() != TokenTypes.SWITCH_RULE;

This mistakenly filters out real lambdas, as in the given breaking example above, both real and fake arrows are direct children of SWITCH_RULE:

|--SWITCH_RULE -> SWITCH_RULE [8:13]
|   |   `--EXPR -> EXPR [8:18]
|   |--LAMBDA -> -> [8:20]     // fake switch-rule arrow, should be filtered
|   |--LAMBDA -> -> [8:28]    // real lambda arrow, should not be filtered
|   |   |--IDENT -> Word [8:23]
|   |   `--EXPR -> EXPR [8:40]
...

The correct filtering implementation is to simply check the presence of children, because it has been empirically proven that a LAMBDA is a real lambda arrow if and only if it has at least one child. (see https://github.com/checkstyle/checkstyle/pull/21540#pullrequestreview-5166211027)

Correct

java
final boolean isRealLambda= lambda.hasChildren();

I've identified four checks that fall for this trap:

  1. ExpressionOverBlockLambda (#21515)
  2. NeedBraces (#21579)
  3. LambdaParameterName (this issue)
  4. LambdaBodyLengthCheck

Considering the fact that filtering real lambdas is prone to mistakes, should we implement a single source of truth somewhere in the util files?