{"record":{"id":"98e94d380f4f3714","repo":"grpc/grpc-java","slug":"httpattributescelmatchinput-cannot-be-used-with-ma","errorCode":null,"errorMessage":"HttpAttributesCelMatchInput cannot be used with MatcherTree","messagePattern":"HttpAttributesCelMatchInput cannot be used with MatcherTree","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"xds/src/main/java/io/grpc/xds/internal/matcher/MatcherTree.java","lineNumber":47,"sourceCode":"final class MatcherTree extends UnifiedMatcher {\n  private static final String TYPE_URL_HTTP_ATTRIBUTES_CEL_INPUT =\n      \"type.googleapis.com/xds.type.matcher.v3.HttpAttributesCelMatchInput\";\n  private final MatchInput input;\n  @Nullable \n  private final Map<String, OnMatch> exactMatchMap;\n  @Nullable \n  private final PrefixTrie prefixTrie;\n  @Nullable \n  private final OnMatch onNoMatch;\n  \n  MatcherTree(Matcher.MatcherTree proto, @Nullable Matcher.OnMatch onNoMatchProto,\n      Predicate<String> actionValidator) {\n    if (!proto.hasInput()) {\n      throw new IllegalArgumentException(\"MatcherTree must have input\");\n    }\n    if (proto.getInput().getTypedConfig().getTypeUrl()\n        .equals(TYPE_URL_HTTP_ATTRIBUTES_CEL_INPUT)) {\n      throw new IllegalArgumentException(\n          \"HttpAttributesCelMatchInput cannot be used with MatcherTree\");\n    }\n    \n    if (proto.hasCustomMatch()) {\n      throw new IllegalArgumentException(\"MatcherTree does not support custom_match\");\n    }\n    \n    this.input = UnifiedMatcher.resolveInput(proto.getInput());\n    \n    if (proto.hasExactMatchMap()) {\n      Matcher.MatcherTree.MatchMap matchMap = proto.getExactMatchMap();\n      if (matchMap.getMapCount() == 0) {\n        throw new IllegalArgumentException(\n            \"MatcherTree exact_match_map must contain at least one entry\");\n      }\n      this.exactMatchMap = new HashMap<>();\n      for (Map.Entry<String, Matcher.OnMatch> entry : \n          matchMap.getMapMap().entrySet()) {","sourceCodeStart":29,"sourceCodeEnd":65,"githubUrl":"https://github.com/grpc/grpc-java/blob/64daddc1f3d1975670f769f3e97bde8b2ba32d25/xds/src/main/java/io/grpc/xds/internal/matcher/MatcherTree.java#L29-L65","documentation":"MatcherTree matches on a single scalar key derived from its input; HttpAttributesCelMatchInput (a CEL-based multi-attribute input) is incompatible with tree matching, so the constructor rejects it explicitly. Use it with MatcherList predicates instead, where multiple CEL expressions can be evaluated.","triggerScenarios":"Constructing MatcherTree whose input TypedExtensionConfig type_url equals TYPE_URL_HTTP_ATTRIBUTES_CEL_INPUT (HttpAttributesCelMatchInput).","commonSituations":"Reusing the same input config block when switching a matcher from list form to tree form; copying an Envoy config that uses CEL input with a list matcher into a tree matcher.","solutions":["Replace the input with a single-key input like HttpRequestHeaderMatchInput.","Move the CEL expression into a MatcherList FieldMatcher predicate (custom_match with CelMatchInput) instead of a MatcherTree.","If tree semantics are required, compute the key upstream (e.g. into a header) and match on that header."],"exampleFix":"// before\n{\"matcher_tree\": {\"input\": {\"typed_config\": {\"@type\": \".../HttpAttributesCelMatchInput\"}}, \"exact_match_map\": {...}}}\n// after\n{\"matcher_tree\": {\"input\": {\"typed_config\": {\"@type\": \".../HttpRequestHeaderMatchInput\", \"header_name\": \"x-key\"}}, \"exact_match_map\": {...}}}","handlingStrategy":"validation","validationCode":"String typeUrl = treeProto.getInput().getTypedConfig().getTypeUrl();\nif (typeUrl.endsWith(\"HttpAttributesCelMatchInput\")) {\n  throw new IllegalArgumentException(\"HttpAttributesCelMatchInput is not valid for MatcherTree\");\n}","typeGuard":"boolean isTreeCompatibleInput(TypedExtensionConfig input) {\n  return !input.getTypedConfig().getTypeUrl().endsWith(\"HttpAttributesCelMatchInput\");\n}","tryCatchPattern":"try {\n  matcherTree = new MatcherTree(proto, onNoMatch, validator);\n} catch (IllegalArgumentException e) {\n  if (e.getMessage().contains(\"HttpAttributesCelMatchInput\")) {\n    // rewrite as MatcherList with CEL predicate\n  }\n  throw e;\n}","preventionTips":["Use HttpRequestHeaderMatchInput (or similar single-key input) for MatcherTree","Reserve CEL input for MatcherList predicates","Document input-to-tree compatibility in config templates"],"tags":["xds","matcher","incompatible-input"],"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-17T15:17:12.973Z"}