{"record":{"id":"1e5bc808fab16afb","repo":"grpc/grpc-java","slug":"unsupported-action-type-typeurl","errorCode":null,"errorMessage":"Unsupported action type: ${typeUrl}","messagePattern":"Unsupported action type: (.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"xds/src/main/java/io/grpc/xds/internal/matcher/OnMatch.java","lineNumber":42,"sourceCode":"/**\n * Handles the action to take upon a match (recurse or return action).\n */\nfinal class OnMatch {\n  @Nullable private final UnifiedMatcher nestedMatcher;\n  @Nullable private final TypedExtensionConfig action;\n  final boolean keepMatching;\n  \n  OnMatch(Matcher.OnMatch proto, Predicate<String> actionValidator) {\n    this.keepMatching = proto.getKeepMatching();\n    if (proto.hasMatcher()) {\n      this.nestedMatcher = UnifiedMatcher.fromProto(proto.getMatcher(), actionValidator);\n      this.action = null;\n    } else if (proto.hasAction()) {\n      this.nestedMatcher = null;\n      this.action = proto.getAction();\n      String typeUrl = this.action.getTypedConfig().getTypeUrl();\n      if (!actionValidator.test(typeUrl)) {\n        throw new IllegalArgumentException(\"Unsupported action type: \" + typeUrl);\n      }\n    } else {\n      throw new IllegalArgumentException(\"OnMatch must have either matcher or action\");\n    }\n  }\n  \n  MatchResult evaluate(MatchContext context) {\n    if (nestedMatcher != null) {\n      return nestedMatcher.match(context);\n    }\n    return MatchResult.create(action);\n  }\n}\n","sourceCodeStart":24,"sourceCodeEnd":56,"githubUrl":"https://github.com/grpc/grpc-java/blob/64daddc1f3d1975670f769f3e97bde8b2ba32d25/xds/src/main/java/io/grpc/xds/internal/matcher/OnMatch.java#L24-L56","documentation":"When an OnMatch references an action (a TypedExtensionConfig) instead of a nested matcher, the action's type_url must be accepted by the configured actionValidator predicate; otherwise the constructor throws, naming the unsupported typeUrl. This prevents routing actions the surrounding framework (e.g. virtual host / cluster wiring) cannot handle.","triggerScenarios":"Constructing OnMatch from a Matcher.OnMatch proto with hasAction() true whose action.getTypedConfig().getTypeUrl() fails actionValidator.test(typeUrl) — e.g. an action type the matcher was not configured to accept.","commonSituations":"Route action types like Route or ClusterWeight not registered in the validator when matchers are used in a context that only supports certain actions; new Envoy action types used before support is added.","solutions":["Use an action typeUrl accepted by the actionValidator passed to the matcher builder (check which actions that context supports).","Update the actionValidator wiring to allow the intended action type if it should be supported.","Replace the action with a nested matcher, or refactor the config so the matcher resolves to a supported action."],"exampleFix":"// before\n{\"on_match\": {\"action\": {\"typed_config\": {\"@type\": \".../Route\"}}}}  // validator rejects Route\n// after\n{\"on_match\": {\"action\": {\"typed_config\": {\"@type\": \".../ClusterWeight\", \"name\": \"c\", \"weight\": 100}}}}","handlingStrategy":"validation","validationCode":"String typeUrl = onMatchProto.getAction().getTypedConfig().getTypeUrl();\nif (!allowedActionUrls.contains(typeUrl)) {\n  throw new IllegalArgumentException(\"action not allowed in this context: \" + typeUrl);\n}","typeGuard":"boolean isSupportedAction(TypedExtensionConfig action, Predicate<String> actionValidator) {\n  return actionValidator.test(action.getTypedConfig().getTypeUrl());\n}","tryCatchPattern":"try {\n  onMatch = new OnMatch(proto, actionValidator);\n} catch (IllegalArgumentException e) {\n  logger.warn(\"unsupported action in on_match: \" + e.getMessage());\n  throw new StatusRuntimeException(Status.INVALID_ARGUMENT.withDescription(e.getMessage()));\n}","preventionTips":["Keep the set of validator-accepted action typeUrls documented next to matcher wiring","Before adding new Envoy action types, extend actionValidator","Prefer nested matchers when the context does not define supported actions"],"tags":["xds","matcher","unsupported-action"],"backgroundTag":"unsupported-enum-value","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"}