grpc/grpc-java · error · IllegalArgumentException
CEL expression must evaluate to string, got: ${ast.getResult
Error message
CEL expression must evaluate to string, got: ${ast.getResultType()} What it means
CelStringExtractor.compile() requires the CEL AST's result type to be STRING (or DYN), because the extractor evaluates the expression to produce a header/value string for downstream matching. Any other result type is rejected at compile time with IllegalArgumentException naming the actual type.
Source
Thrown at xds/src/main/java/io/grpc/xds/internal/matcher/CelStringExtractor.java:46
*/
final class CelStringExtractor {
private final CelRuntime.Program program;
@Nullable
private final String defaultValue;
private CelStringExtractor(CelRuntime.Program program, @Nullable String defaultValue) {
this.program = program;
this.defaultValue = defaultValue;
}
/**
* Compiles the AST into a CelStringExtractor with an optional default value.
* Throws an Exception if evaluation fails during compilation setup.
*/
static CelStringExtractor compile(CelAbstractSyntaxTree ast, @Nullable String defaultValue)
throws CelEvaluationException {
if (ast.getResultType() != SimpleType.STRING && ast.getResultType() != SimpleType.DYN) {
throw new IllegalArgumentException(
"CEL expression must evaluate to string, got: " + ast.getResultType());
}
CelCommon.checkAllowedReferences(ast);
CelRuntime.Program program = CelCommon.RUNTIME.createProgram(ast);
return new CelStringExtractor(program, defaultValue);
}
/**
* Compiles the AST into a CelStringExtractor with no default value.
* Throws an Exception if evaluation fails during compilation setup.
*/
static CelStringExtractor compile(CelAbstractSyntaxTree ast)
throws CelEvaluationException {
return compile(ast, null);
}
/**
* Evaluates the CEL expression and returns the string result.View on GitHub (pinned to 64daddc1f3)
Solutions
- Change the expression so it evaluates to a string, e.g. request.headers['x-user-id'] or string(tls.san).
- Wrap non-string values with CEL conversions: string(...) for ints, or a ternary producing string branches.
- If a boolean predicate is actually needed, use CelMatcher.compile() instead of CelStringExtractor.compile().
Example fix
// before
compile(compiler.compile("request.host == 'edge'"), null); // bool
// after
compile(compiler.compile("request.headers['x-user-id']"), "anonymous"); Defensive patterns
Strategy: validation
Validate before calling
if (ast.getResultType() != SimpleType.STRING && ast.getResultType() != SimpleType.DYN) {
throw new IllegalArgumentException("CEL expr must be string, got: " + ast.getResultType());
} Type guard
boolean isStringAst(CelAbstractSyntaxTree ast) {
return ast.getResultType() == SimpleType.STRING || ast.getResultType() == SimpleType.DYN;
} Try / catch
try { return CelStringExtractor.compile(ast, def); }
catch (IllegalArgumentException e) { logger.warn("non-string CEL expr", e); return null; } Prevention
- Use value expressions (request.headers['x']) not predicates for extractors.
- Coerce with string(...) when the underlying value is numeric.
- Provide a defaultValue to make extraction resilient.
When it happens
Trigger: Calling CelStringExtractor.compile(ast, defaultValue) with an AST whose getResultType() is, e.g., SimpleType.BOOL or INT — typically a predicate expression like 'a == b' passed where a value expression like 'request.headers["x-user"]' is expected.
Common situations: Copy-pasting a boolean matcher expression into the extractor position; control plane generating int/bool-typed attribute expressions; schema migration changing the expression's inferred type.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- CEL expression must evaluate to boolean, got:
- Unsupported input type for CEL evaluation: ${input class nam
- Unsupported input type for CEL evaluation:
- 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/9563b7f789e12eb4.
Report an issue: GitHub.