{"record":{"id":"622c0f09bffa3390","repo":"grpc/grpc-go","slug":"weighted-target-no-targets-to-pick-from","errorCode":null,"errorMessage":"weighted-target: no targets to pick from","messagePattern":"weighted-target: no targets to pick from","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"balancer/weightedtarget/weightedaggregator/aggregator.go","lineNumber":259,"sourceCode":"\t\t// need to call it when they are resumed.\n\t\twbsa.needUpdateStateOnResume = true\n\t\treturn\n\t}\n\n\twbsa.cc.UpdateState(wbsa.build())\n}\n\n// build combines sub-states into one.\n//\n// Caller must hold wbsa.mu.\nfunc (wbsa *Aggregator) build() balancer.State {\n\twbsa.logger.Infof(\"Child pickers with config: %+v\", wbsa.idToPickerState)\n\n\tif len(wbsa.idToPickerState) == 0 {\n\t\t// This is the case when all sub-balancers are removed.\n\t\treturn balancer.State{\n\t\t\tConnectivityState: connectivity.TransientFailure,\n\t\t\tPicker:            base.NewErrPicker(errors.New(\"weighted-target: no targets to pick from\")),\n\t\t}\n\t}\n\n\t// Make sure picker's return error is consistent with the aggregatedState.\n\tpickers := make([]weightedPickerState, 0, len(wbsa.idToPickerState))\n\n\tswitch aggState := wbsa.csEvltr.CurrentState(); aggState {\n\tcase connectivity.Connecting:\n\t\treturn balancer.State{\n\t\t\tConnectivityState: aggState,\n\t\t\tPicker:            base.NewErrPicker(balancer.ErrNoSubConnAvailable)}\n\tcase connectivity.TransientFailure:\n\t\t// this means that all sub-balancers are now in TransientFailure.\n\t\tfor _, ps := range wbsa.idToPickerState {\n\t\t\tpickers = append(pickers, *ps)\n\t\t}\n\t\treturn balancer.State{\n\t\t\tConnectivityState: aggState,","sourceCodeStart":241,"sourceCodeEnd":277,"githubUrl":"https://github.com/grpc/grpc-go/blob/0c51461d27177d997e14c642fe18c11668fc09a3/balancer/weightedtarget/weightedaggregator/aggregator.go#L241-L277","documentation":"Thrown by StringMatcherFromProto in its default switch case when the StringMatcher proto's MatchPattern oneof is set to a variant that the library does not recognize. As of the current code, the handled variants are Exact, Prefix, Suffix, SafeRegex, and Contains. Any other oneof variant (or a nil match pattern with a new proto field) falls through to this error.","triggerScenarios":"A future or custom go-control-plane version adds a new StringMatcher variant (e.g., a hypothetical 'glob' type) and the control plane sends it, but grpc-go's StringMatcherFromProto was compiled against an older proto that does not have a case for it. The switch falls through to default.","commonSituations":"Version skew: the control plane uses a newer envoy.type.matcher.v3.StringMatcher proto with additional match pattern variants. A custom or patched go-control-plane that adds non-standard oneof fields. A proto deserialization quirk where GetMatchPattern() returns a type the switch does not enumerate.","solutions":["Upgrade grpc-go (and its bundled go-control-plane dependency) to a version whose StringMatcherFromProto handles the variant the control plane sends.","Downgrade or patch the control plane to only use supported StringMatcher variants: exact, prefix, suffix, safe_regex, or contains.","File an issue / contribute a case to StringMatcherFromProto for the new variant if it is part of the upstream proto spec."],"exampleFix":"// before: control plane sends a new matcher variant not yet supported\nstring_matcher:\n  some_new_match_type: \"value\"\n\n// after: use a supported variant\nstring_matcher:\n  exact: \"value\"","handlingStrategy":"validation","validationCode":"// Check that the StringMatcher uses a known variant before constructing:\nfunc validateStringMatcherProto(sm *v3matcherpb.StringMatcher) error {\n    switch sm.GetMatchPattern().(type) {\n    case *v3matcherpb.StringMatcher_Exact,\n        *v3matcherpb.StringMatcher_Prefix,\n        *v3matcherpb.StringMatcher_Suffix,\n        *v3matcherpb.StringMatcher_SafeRegex,\n        *v3matcherpb.StringMatcher_Contains:\n        return nil\n    default:\n        return fmt.Errorf(\"unsupported StringMatcher variant: %T\", sm.GetMatchPattern())\n    }\n}","typeGuard":"func isSupportedStringMatcher(sm *v3matcherpb.StringMatcher) bool {\n    switch sm.GetMatchPattern().(type) {\n    case *v3matcherpb.StringMatcher_Exact,\n        *v3matcherpb.StringMatcher_Prefix,\n        *v3matcherpb.StringMatcher_Suffix,\n        *v3matcherpb.StringMatcher_SafeRegex,\n        *v3matcherpb.StringMatcher_Contains:\n        return true\n    }\n    return false\n}","tryCatchPattern":null,"preventionTips":["Pin go-control-plane versions so the StringMatcher proto does not introduce unknown variants.","When upgrading go-control-plane, grep StringMatcherFromProto for new case branches and add them.","Use only the five canonical StringMatcher variants in control-plane templates."],"tags":["xds","matcher","grpc","proto","version-skew"],"backgroundTag":null,"analyzedSha":"0c51461d27177d997e14c642fe18c11668fc09a3","analyzedAt":"2026-08-11T14:49:15.055Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}