elastic/elasticsearch · error · IllegalArgumentException
cannot use a static method as a function reference [%s::%s/%
Error message
cannot use a static method as a function reference [%s::%s/%d] with a non-static captured variable
What it means
FunctionRef.create throws this IllegalArgumentException at compile time when a static method is used as a function reference with a non-static captured variable. The compiler first resolves the method as an augmented (instance) method; if that succeeds but the reference also requires capturing an instance (numberOfCaptures == 1), the method is static and cannot accept a receiver capture. Painless rejects this because a static method has no 'this' to bind.
Source
Thrown at modules/lang-painless/src/main/java/org/elasticsearch/painless/FunctionRef.java:204
methodName,
captured ? interfaceTypeParametersSize : interfaceTypeParametersSize - 1
);
if (painlessMethod == null) {
throw new IllegalArgumentException(
Strings.format(
"function reference [%s::%s/%d] matching [%s, %s/%d] not found",
typeName,
methodName,
interfaceTypeParametersSize,
targetClassName,
interfaceMethodName,
interfaceTypeParametersSize
)
);
}
} else if (captured) {
throw new IllegalArgumentException(
Strings.format(
"cannot use a static method as a function reference [%s::%s/%d] with a non-static captured variable",
typeName,
methodName,
interfaceTypeParametersSize
)
);
}
delegateClassName = painlessMethod.javaMethod().getDeclaringClass().getName();
isDelegateInterface = painlessMethod.javaMethod().getDeclaringClass().isInterface();
isDelegateAugmented = painlessMethod.javaMethod().getDeclaringClass() != painlessMethod.targetClass();
if (Modifier.isStatic(painlessMethod.javaMethod().getModifiers())) {
delegateInvokeType = H_INVOKESTATIC;
} else if (isDelegateInterface) {
delegateInvokeType = H_INVOKEINTERFACE;
} else {View on GitHub (pinned to db6a809a66)
Solutions
- If the method is static, use the class-qualified form (Type::method) without an instance capture.
- If you need an instance binding, ensure the referenced method is an instance (non-static) method.
- Rewrite as an explicit lambda to make the binding explicit: '() -> Type.method()' or '() -> instance.method()'.
Example fix
// before String s = '42'; Supplier<Integer> f = s::parseInt; // parseInt is static // after Supplier<Integer> f = () -> Integer.parseInt(s);
Defensive patterns
Strategy: validation
Validate before calling
// Use class-qualified form for static methods; instance form only for instance methods: // // Static: Function<String,Integer> f = Integer::parseInt; // // Instance: Function<String,String> f = String::toUpperCase;
Prevention
- Do not capture an instance for a static method reference.
- Use Type::method for static methods, instance::method for instance methods.
- Rewrite as a lambda when binding semantics are unclear.
When it happens
Trigger: Writing a method reference that captures an instance variable but resolves to a static method: 'String s = 'abc'; Supplier<Integer> len = s::valueOf;' where valueOf is static but the reference tries to capture s as a receiver. The augmented lookup finds the static method, but the capture flag indicates an instance binding is expected.
Common situations: Confusion between static and instance method references (e.g. Type::method vs instance::method). Refactoring a method to static without updating the reference syntax. Capturing an instance for a method that is actually static.
Related errors
- cannot convert function reference [%s::%s] to a non-function
- function reference [this::%s] matching [%s, %s/%d] not found
- function reference [%s::%s/%d] matching [%s, %s/%d] not foun
- Cannot apply operator [{}] to type [{}]
- Cannot apply operator [{}] to types [{}] and [{}]
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/b627b5bb39cf951d.
Report an issue: GitHub.