{"record":{"id":"e3b1add496f17915","repo":"grpc/grpc-go","slug":"randomsubsetting-error-switching-to-child-of-type","errorCode":null,"errorMessage":"randomsubsetting: error switching to child of type %q: %v","messagePattern":"randomsubsetting: error switching to child of type %q: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"balancer/randomsubsetting/randomsubsetting.go","lineNumber":130,"sourceCode":"\thashSeed   uint64\n\thashDigest *xxhash.Digest\n}\n\nfunc (b *subsettingBalancer) UpdateClientConnState(s balancer.ClientConnState) error {\n\tlbCfg, ok := s.BalancerConfig.(*lbConfig)\n\tif !ok {\n\t\tb.logger.Warningf(\"Received config with unexpected type %T: %v\", s.BalancerConfig, s.BalancerConfig)\n\t\treturn balancer.ErrBadResolverState\n\t}\n\n\t// Build config for the gracefulswitch balancer. It is safe to ignore\n\t// JSON marshaling errors here, since the config was already validated\n\t// as part of ParseConfig().\n\tcfg := []map[string]any{{lbCfg.ChildPolicy.Name: lbCfg.ChildPolicy.Config}}\n\tcfgJSON, _ := json.Marshal(cfg)\n\tparsedCfg, err := gracefulswitch.ParseConfig(cfgJSON)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"randomsubsetting: error switching to child of type %q: %v\", lbCfg.ChildPolicy.Name, err)\n\t}\n\tb.cfg = lbCfg\n\tendpoints := resolver.State{\n\t\tEndpoints:     b.calculateSubset(s.ResolverState.Endpoints),\n\t\tServiceConfig: s.ResolverState.ServiceConfig,\n\t\tAttributes:    s.ResolverState.Attributes,\n\t}\n\n\treturn b.Balancer.UpdateClientConnState(balancer.ClientConnState{\n\t\tResolverState:  endpoints,\n\t\tBalancerConfig: parsedCfg,\n\t})\n}\n\n// calculateSubset implements the subsetting algorithm, as described in A68:\n// https://github.com/grpc/proposal/blob/master/A68-random-subsetting.md#subsetting-algorithm\nfunc (b *subsettingBalancer) calculateSubset(endpoints []resolver.Endpoint) []resolver.Endpoint {\n\t// A helper struct to hold an endpoint and its hash.","sourceCodeStart":112,"sourceCodeEnd":148,"githubUrl":"https://github.com/grpc/grpc-go/blob/0c51461d27177d997e14c642fe18c11668fc09a3/balancer/randomsubsetting/randomsubsetting.go#L112-L148","documentation":"Returned by random_subsetting's UpdateClientConnState() (balancer/randomsubsetting/randomsubsetting.go:130) when gracefulswitch.ParseConfig() fails for the configured child policy. The %q is the child policy name, %v the underlying error. This means the child policy is either not registered or its own config is invalid, so the subsetting balancer cannot switch to it.","triggerScenarios":"After ParseConfig succeeds, UpdateClientConnState marshals the child config and calls gracefulswitch.ParseConfig(cfgJSON) at line 128. If the child policy name is unknown (not registered via balancer.Register) or the child's own ParseConfig rejects the config, the error is wrapped at line 130.","commonSituations":"childPolicy references a balancer whose package was not imported (blank import missing), e.g. round_robin not registered; the child's config is structurally invalid; the child policy name is misspelled; using a child policy provided by a package not linked into the binary.","solutions":["Ensure the child policy package is blank-imported so it self-registers (e.g. import _ \"google.golang.org/grpc/balancer/roundrobin\").","Verify the child policy name in the config matches a registered builder Name().","Inspect the %v for the child's own validation error and fix the child config.","Check that the grpc-go version includes the child policy you reference."],"exampleFix":"// before: round_robin not registered (missing blank import)\nimport (\n  _ \"google.golang.org/grpc/balancer/randomsubsetting\"\n)\n// childPolicy [{\"round_robin\":{}}] → gracefulswitch.ParseConfig fails\n\n// after: also blank-import the child policy package\nimport (\n  _ \"google.golang.org/grpc/balancer/randomsubsetting\"\n  _ \"google.golang.org/grpc/balancer/roundrobin\"\n)","handlingStrategy":"validation","validationCode":"// Ensure the child policy is registered before using random_subsetting.\nfunc ensureChildRegistered(name string) bool {\n    return balancer.Get(name) != nil\n}\n// Usage:\n// if !ensureChildRegistered(\"round_robin\") { panic(\"round_robin not registered\") }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Blank-import every child policy package your config references (e.g. _ \"google.golang.org/grpc/balancer/roundrobin\").","At startup, assert balancer.Get(childName) != nil for each configured child.","Validate the child's own config JSON before composing it under random_subsetting."],"tags":["grpc","balancer","random-subsetting","child-policy","config","registration"],"backgroundTag":null,"analyzedSha":"0c51461d27177d997e14c642fe18c11668fc09a3","analyzedAt":"2026-08-11T14:49:15.055Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}