grpc/grpc-java · error · CelEvaluationException
Unsupported input type for CEL evaluation: ${input class nam
Error message
Unsupported input type for CEL evaluation: ${input class name or null} What it means
CelStringExtractor.extract() evaluates the CEL program only when the input is a CelVariableResolver; for any other input type it must either return the configured defaultValue or, when no default was supplied, throw CelEvaluationException. The message reports 'null' or the offending class name. Unlike CelMatcher, extract() tolerates evaluation failures when a default exists, but unsupported input types with no default are fatal.
Source
Thrown at xds/src/main/java/io/grpc/xds/internal/matcher/CelStringExtractor.java:82
* Evaluates the CEL expression and returns the string result.
* Returns the default value if the result is not a string or if evaluation
* fails.
*/
String extract(Object input) throws CelEvaluationException {
if (input instanceof CelVariableResolver) {
try {
Object result = program.eval((CelVariableResolver) input);
if (result instanceof String) {
return (String) result;
}
} catch (CelEvaluationException e) {
if (defaultValue == null) {
throw e;
}
}
} else if (defaultValue == null) {
throw new CelEvaluationException(
"Unsupported input type for CEL evaluation: "
+ (input == null ? "null" : input.getClass().getName()));
}
return defaultValue;
}
}
View on GitHub (pinned to 64daddc1f3)
Solutions
- Implement CelVariableResolver around your request context and pass that to extract().
- Supply a defaultValue (e.g. "unknown") when compiling so extraction degrades gracefully instead of throwing.
- Null-check input and construct a resolver before calling extract().
Example fix
// before String v = extractor.extract(headersMap); // throws, no default // after String v = extractor.extract(new HeaderResolver(headersMap)); // or compile with a default: CelStringExtractor.compile(ast, "unknown");
Defensive patterns
Strategy: fallback
Validate before calling
if (input == null || !(input instanceof CelVariableResolver)) {
return defaultValue; // or build a resolver first
} Type guard
boolean isExtractable(Object input) { return input instanceof CelVariableResolver; } Try / catch
try { return extractor.extract(resolver); }
catch (CelEvaluationException e) { return defaultValue != null ? defaultValue : ""; } Prevention
- Compile extractors with a sensible defaultValue.
- Route all inputs through a CelVariableResolver adapter.
- Test extraction against null and non-resolver inputs in CI.
When it happens
Trigger: extract() is called with null or a non-CelVariableResolver object (e.g. a raw Map or proto) while defaultValue == null, so the else-branch throws. Tests extract_unsupportedInputType_throws and extract_evaluationError_throws cover these paths.
Common situations: Forgetting to supply a default value when wiring the extractor while passing non-resolver inputs; calling extract() from generic code that handles multiple input shapes; null headers/attributes on a request path.
Understand the failure class
Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.
Related errors
- Unsupported input type for CEL evaluation:
- CEL expression must evaluate to string, got: ${ast.getResult
- CEL expression must evaluate to boolean, got:
- CelMatcher must have expr_match
- CelMatcher must have cel_expr_checked
AI-assisted analysis of grpc/grpc-java@64daddc1f3 (2026-09-08).
Data as JSON: /api/errors/60a64e11fdab7d5b.
Report an issue: GitHub.