{"record":{"id":"60a64e11fdab7d5b","repo":"grpc/grpc-java","slug":"unsupported-input-type-for-cel-evaluation-input","errorCode":null,"errorMessage":"Unsupported input type for CEL evaluation: ${input class name or null}","messagePattern":"Unsupported input type for CEL evaluation: (.+?)","errorType":"validation","errorClass":"CelEvaluationException","httpStatus":null,"severity":"error","filePath":"xds/src/main/java/io/grpc/xds/internal/matcher/CelStringExtractor.java","lineNumber":82,"sourceCode":"   * Evaluates the CEL expression and returns the string result.\n   * Returns the default value if the result is not a string or if evaluation\n   * fails.\n   */\n  String extract(Object input) throws CelEvaluationException {\n    if (input instanceof CelVariableResolver) {\n      try {\n        Object result = program.eval((CelVariableResolver) input);\n\n        if (result instanceof String) {\n          return (String) result;\n        }\n      } catch (CelEvaluationException e) {\n        if (defaultValue == null) {\n          throw e;\n        }\n      }\n    } else if (defaultValue == null) {\n      throw new CelEvaluationException(\n          \"Unsupported input type for CEL evaluation: \"\n              + (input == null ? \"null\" : input.getClass().getName()));\n    }\n    return defaultValue;\n  }\n}\n","sourceCodeStart":64,"sourceCodeEnd":89,"githubUrl":"https://github.com/grpc/grpc-java/blob/64daddc1f3d1975670f769f3e97bde8b2ba32d25/xds/src/main/java/io/grpc/xds/internal/matcher/CelStringExtractor.java#L64-L89","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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()."],"exampleFix":"// before\nString v = extractor.extract(headersMap); // throws, no default\n// after\nString v = extractor.extract(new HeaderResolver(headersMap));\n// or compile with a default:\nCelStringExtractor.compile(ast, \"unknown\");","handlingStrategy":"fallback","validationCode":"if (input == null || !(input instanceof CelVariableResolver)) {\n  return defaultValue; // or build a resolver first\n}","typeGuard":"boolean isExtractable(Object input) { return input instanceof CelVariableResolver; }","tryCatchPattern":"try { return extractor.extract(resolver); }\ncatch (CelEvaluationException e) { return defaultValue != null ? defaultValue : \"\"; }","preventionTips":["Compile extractors with a sensible defaultValue.","Route all inputs through a CelVariableResolver adapter.","Test extraction against null and non-resolver inputs in CI."],"tags":["cel","grpc-xds","unsupported-type","extractor"],"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-14T00:17:10.932Z"}