{"record":{"id":"b5e237a1ecb21e87","repo":"grpc/grpc-java","slug":"type-mismatch-input-input-output-type-not-comp","errorCode":null,"errorMessage":"Type mismatch: input ${input output type} not compatible with matcher ${matcher input type}","messagePattern":"Type mismatch: input (.+?) not compatible with matcher (.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"xds/src/main/java/io/grpc/xds/internal/matcher/PredicateEvaluator.java","lineNumber":75,"sourceCode":"        Matchers.StringMatcher stringMatcher =\n            MatcherParser.parseStringMatcher(proto.getValueMatch());\n        this.matcher = new StringMatcherAdapter(stringMatcher);\n      } else if (proto.hasCustomMatch()) {\n        TypedExtensionConfig customConfig = proto.getCustomMatch();\n        MatcherProvider provider = MatcherRegistry.getDefaultRegistry()\n            .getMatcherProvider(customConfig.getTypedConfig().getTypeUrl());\n        if (provider == null) {\n          throw new IllegalArgumentException(\"Unsupported custom_match matcher: \" \n              + customConfig.getTypedConfig().getTypeUrl());\n        }\n        this.matcher = provider.getMatcher(customConfig);\n      } else {\n        throw new IllegalArgumentException(\n            \"SinglePredicate must have either value_match or custom_match\");\n      }\n\n      if (!input.outputType().equals(matcher.inputType())) {\n        throw new IllegalArgumentException(\"Type mismatch: input \" + input.outputType().getName()\n            + \" not compatible with matcher \" + matcher.inputType().getName());\n      }\n    }\n    \n    @Override \n    boolean evaluate(MatchContext context) {\n      return matcher.match(input.apply(context));\n    }\n    \n\n\n    private static final class StringMatcherAdapter implements Matcher {\n      private final Matchers.StringMatcher stringMatcher;\n\n      StringMatcherAdapter(Matchers.StringMatcher stringMatcher) {\n        this.stringMatcher = stringMatcher;\n      }\n","sourceCodeStart":57,"sourceCodeEnd":93,"githubUrl":"https://github.com/grpc/grpc-java/blob/64daddc1f3d1975670f769f3e97bde8b2ba32d25/xds/src/main/java/io/grpc/xds/internal/matcher/PredicateEvaluator.java#L57-L93","documentation":"The resolved MatchInput produces a value of some Java type (input.outputType()), and the chosen Matcher accepts values of matcher.inputType(). The evaluator enforces their compatibility at construction; when the input's output type is not assignable to the matcher's expected input type it throws this IllegalArgumentException so mismatches fail fast instead of at match time.","triggerScenarios":"Constructing SinglePredicateEvaluator where the input's outputType() (e.g. an int or IPAddress-producing input) differs from the matcher's inputType() (e.g. String) — e.g. pairing a header-string input with a custom matcher that expects an IP type, or a value_match typed for a different input class.","commonSituations":"Mixing inputs and matchers from different xDS extensions; copy-pasted predicate blocks where input was swapped but value_match kept; new custom input/matcher plugin pairs whose declared types disagree.","solutions":["Change either the input or the matcher so matcher.inputType() equals input.outputType() (e.g. use an IP-typed custom matcher with an IP-producing input)","Use a value_match (StringMatcher) with a String-producing input such as header/hostname inputs","Add a registry-level type compatibility check when registering custom inputs and matchers so bad pairs are rejected with a clearer message"],"exampleFix":"// before: header (String) input with IP-typed matcher\nSinglePredicate.newBuilder().setInput(headerInput)\n    .setCustomMatch(ipMatcherExtension).build(); // Type mismatch\n// after\nSinglePredicate.newBuilder().setInput(headerInput)\n    .setValueMatch(StringMatcher.newBuilder().setExact(\"1.2.3.4\")).build();","handlingStrategy":"validation","validationCode":"MatchInput input = UnifiedMatcher.resolveInput(proto.getInput());\nMatcher matcher = /* resolved matcher */;\nif (!input.outputType().equals(matcher.inputType())) {\n  throw new IllegalArgumentException(\"input/matcher type mismatch\");\n}","typeGuard":null,"tryCatchPattern":"try { new PredicateEvaluator.SinglePredicateEvaluator(proto); } catch (IllegalArgumentException e) { log.error(\"Type mismatch in predicate: \" + e.getMessage()); throw new ConfigException(e); }","preventionTips":["Pair inputs and matchers with matching declared types","Use StringMatcher only with String-producing inputs","Type-check custom input/matcher pairs at registration time"],"tags":["xds","matcher","type-mismatch","grpc"],"backgroundTag":"type-mismatch","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"}