elastic/elasticsearch · error · LambdaConversionException
lambda expects return type [{}], but found return type [void
Error message
lambda expects return type [{}], but found return type [void] What it means
LambdaBootstrap.validateTypes throws this LambdaConversionException at link time when a lambda's functional interface declares a non-void return type but the delegate method (the lambda body or referenced method) returns void. The JVM's lambda metafactory requires that the SAM method and the implementation agree on return type; a value-returning interface cannot delegate to a void method because there would be no value to return. Painless checks this explicitly to give a clear message before the metafactory fails.
Source
Thrown at modules/lang-painless/src/main/java/org/elasticsearch/painless/LambdaBootstrap.java:359
endLambdaClass(cw);
Class<?> lambdaClass = createLambdaClass(loader, cw, lambdaClassType);
if (captures.length > 0) {
return createCaptureCallSite(lookup, factoryMethodType, lambdaClass);
} else {
return createNoCaptureCallSite(factoryMethodType, lambdaClass);
}
}
/**
* Validates some conversions at link time. Currently, only ensures that the lambda method
* with a return value cannot delegate to a delegate method with no return type.
*/
private static void validateTypes(MethodType interfaceMethodType, MethodType delegateMethodType) throws LambdaConversionException {
if (interfaceMethodType.returnType() != void.class && delegateMethodType.returnType() == void.class) {
throw new LambdaConversionException(
"lambda expects return type [" + interfaceMethodType.returnType() + "], but found return type [void]"
);
}
}
/**
* Creates the {@link ClassWriter} to be used for the lambda class generation.
*/
private static ClassWriter beginLambdaClass(String lambdaClassName, Class<?> lambdaInterface) {
String baseClass = Type.getInternalName(Object.class);
int modifiers = ACC_PUBLIC | ACC_SUPER | ACC_FINAL | ACC_SYNTHETIC;
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
cw.visit(CLASS_VERSION, modifiers, lambdaClassName, null, baseClass, new String[] { Type.getInternalName(lambdaInterface) });
return cw;
}
View on GitHub (pinned to db6a809a66)
Solutions
- Ensure the lambda body returns a value matching the interface's return type.
- Switch to a void-returning functional interface (e.g. Runnable or Consumer) if the body intentionally has no return value.
- If using a method reference, pick a method whose return type matches the interface's SAM return type.
Example fix
// before
Supplier<String> s = () -> { doc['x'].value; }; // body returns void (statement)
// after
Supplier<String> s = () -> doc['x'].value; // expression returns the value Defensive patterns
Strategy: validation
Validate before calling
// Match the lambda body's return type to the interface SAM return type:
// // Supplier<String> s = () -> 'value'; // returns String, matches Supplier.get()
// // Runnable r = () -> { println('x'); }; // void body, matches Runnable.run() Prevention
- Ensure value-returning interfaces (Function, Supplier, Predicate) get a body that returns a value.
- Use Runnable or Consumer for void-returning bodies.
- Prefer expression lambdas over statement lambdas when a return value is needed.
When it happens
Trigger: Writing a lambda or method reference assigned to a functional interface whose method returns a value, but the body or referenced method returns void: 'Supplier<String> s = () -> { System.out.println('hi'); };' — the lambda body returns nothing but Supplier.get() must return a String.
Common situations: Mismatching a lambda body that performs a side effect (no return) with a value-returning functional interface like Function, Supplier, or Predicate. Method references to void-returning methods (e.g. System.out::println) assigned to Function/Supplier types.
Related errors
- Cannot apply operator [{}] to type [{}]
- Cannot apply operator [{}] to types [{}] and [{}]
- Cannot cast {} to {}
- cannot convert function reference [%s::%s] to a non-function
- function reference [this::%s] matching [%s, %s/%d] not found
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/708b734da89e6c76.
Report an issue: GitHub.