{"record":{"id":"cb61d943da49225c","repo":"grpc/grpc-java","slug":"unsupported-input-type-for-cel-evaluation","errorCode":null,"errorMessage":"Unsupported input type for CEL evaluation: ","messagePattern":"Unsupported input type for CEL evaluation: ","errorType":"exception","errorClass":"CelEvaluationException","httpStatus":null,"severity":"error","filePath":"xds/src/main/java/io/grpc/xds/internal/matcher/CelMatcher.java","lineNumber":60,"sourceCode":"    // CelValidationException -> inside cel-compiler -> Forbidden in production signatures\n    if (ast.getResultType() != SimpleType.BOOL) {\n      throw new IllegalArgumentException(\n          \"CEL expression must evaluate to boolean, got: \" + ast.getResultType());\n    }\n    CelCommon.checkAllowedReferences(ast);\n    CelRuntime.Program program = CelCommon.RUNTIME.createProgram(ast);\n    return new CelMatcher(program);\n  }\n\n  /**\n   * Evaluates the CEL expression against the input activation.\n   */\n  boolean match(Object input) throws CelEvaluationException {\n    Object result;\n    if (input instanceof CelVariableResolver) {\n      result = program.eval((CelVariableResolver) input);\n    } else {\n      throw new CelEvaluationException(\n          \"Unsupported input type for CEL evaluation: \"\n               + (input == null ? \"null\" : input.getClass().getName()));\n    }\n    \n    if (result instanceof Boolean) {\n      return (Boolean) result;\n    }\n    throw new CelEvaluationException(\n        \"CEL expression must evaluate to boolean, got: \" + result.getClass().getName());\n  }\n}\n","sourceCodeStart":42,"sourceCodeEnd":72,"githubUrl":"https://github.com/grpc/grpc-java/blob/64daddc1f3d1975670f769f3e97bde8b2ba32d25/xds/src/main/java/io/grpc/xds/internal/matcher/CelMatcher.java#L42-L72","documentation":"CelMatcher.match() only accepts inputs implementing CelVariableResolver, which supplies the variable bindings during CEL evaluation. Any other object (or null) cannot be resolved into variables, so the call is rejected with CelEvaluationException before the program runs. The message includes the offending class name or 'null'.","triggerScenarios":"Passing null, a raw Map, a proto request object, or any non-CelVariableResolver value to CelMatcher.match(). Test methods celMatcher_unsupportedInputThrows and celMatcher_nullInputThrows exercise both cases.","commonSituations":"Calling match() directly with a header map instead of wrapping it in a resolver implementation; refactoring code that previously took typed inputs; unit tests probing null handling.","solutions":["Wrap the evaluation context in a class implementing CelVariableResolver (e.g. a header-map-backed resolver) and pass that to match().","Null-check the input and build a resolver before calling match().","Catch CelEvaluationException at the call site and fall back to a non-match / default decision."],"exampleFix":"// before\nboolean ok = matcher.match(requestHeaders); // Map, unsupported\n// after\nboolean ok = matcher.match(new HeaderResolver(requestHeaders)); // implements CelVariableResolver","handlingStrategy":"type-guard","validationCode":"if (input == null || !(input instanceof CelVariableResolver)) {\n  throw new IllegalArgumentException(\"match() requires a CelVariableResolver\");\n}","typeGuard":"boolean isEvaluable(Object input) { return input instanceof CelVariableResolver; }","tryCatchPattern":"try { return matcher.match(resolver); }\ncatch (CelEvaluationException e) { logger.warn(\"CEL eval failed\", e); return false; }","preventionTips":["Provide a single adapter class implementing CelVariableResolver for your request context.","Never pass raw Maps or protos directly to match().","Add unit tests covering null input behavior."],"tags":["cel","grpc-xds","unsupported-type","evaluation"],"backgroundTag":"incompatible-source-type","analyzedSha":"64daddc1f3d1975670f769f3e97bde8b2ba32d25","analyzedAt":"2026-09-08T06:14:57.704Z","contentChangedAt":"2026-09-08T06:14:57.704Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}