{"record":{"id":"d98b592eaa489871","repo":"grpc/grpc-go","slug":"xds-wrr-locality-invalid-lbconfig-child-policy-f","errorCode":null,"errorMessage":"xds_wrr_locality: invalid LBConfig: child policy field must be set","messagePattern":"xds_wrr_locality: invalid LBConfig: child policy field must be set","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/xds/balancer/wrrlocality/balancer.go","lineNumber":98,"sourceCode":"\t\treturn nil\n\t}\n\twrrL := &wrrLocalityBalancer{\n\t\tchild:       wtb,\n\t\tchildParser: wtbCfgParser,\n\t}\n\n\twrrL.logger = prefixLogger(wrrL)\n\twrrL.logger.Infof(\"Created\")\n\treturn wrrL\n}\n\nfunc (bb) ParseConfig(s json.RawMessage) (serviceconfig.LoadBalancingConfig, error) {\n\tvar lbCfg *LBConfig\n\tif err := json.Unmarshal(s, &lbCfg); err != nil {\n\t\treturn nil, fmt.Errorf(\"xds_wrr_locality: invalid LBConfig: %s, error: %v\", string(s), err)\n\t}\n\tif lbCfg == nil || lbCfg.ChildPolicy == nil {\n\t\treturn nil, errors.New(\"xds_wrr_locality: invalid LBConfig: child policy field must be set\")\n\t}\n\treturn lbCfg, nil\n}\n\ntype attributeKey struct{}\n\n// Equal allows the values to be compared by Attributes.Equal.\nfunc (a AddrInfo) Equal(o any) bool {\n\toa, ok := o.(AddrInfo)\n\treturn ok && oa.LocalityWeight == a.LocalityWeight\n}\n\n// AddrInfo is the locality weight of the locality an address is a part of.\ntype AddrInfo struct {\n\tLocalityWeight uint32\n}\n\n// SetAddrInfo returns a copy of endpoint in which the Attributes field is","sourceCodeStart":80,"sourceCodeEnd":116,"githubUrl":"https://github.com/grpc/grpc-go/blob/03255a9237b6eb32710f6bc4f2de9a675b99fe36/internal/xds/balancer/wrrlocality/balancer.go#L80-L116","documentation":"Returned by the xds_wrr_locality balancer's ParseConfig (wrrlocality/balancer.go:97-98) when the JSON LB config unmarshals to nil or its ChildPolicy field is nil. The weighted-round-robin-per-locality balancer delegates to the weighted_target child, so a missing child_policy makes the config unusable and is rejected at parse time.","triggerScenarios":"Providing an xds_wrr_locality service/LB config JSON whose 'childPolicy' (child_policy) field is absent or null, e.g. {\"xds_wrr_locality\":{}}. The json.Unmarshal succeeds but lbCfg or lbCfg.ChildPolicy is nil.","commonSituations":"Hand-authoring a service config and forgetting childPolicy; a control plane translating xDS endpoint config that drops the child policy; version mismatch where an older field name is used.","solutions":["Add a non-null childPolicy to the xds_wrr_locality config, typically weighted_target or round_robin.","If generating config programmatically, assert childPolicy != nil before serializing.","Validate the JSON against the expected schema (childPolicy is required) before applying via WithServiceConfig."],"exampleFix":"// before\n//   { \"xds_wrr_locality\": {} }\n// after\n//   { \"xds_wrr_locality\": { \"childPolicy\": [ { \"weighted_target\": { \"targets\": {} } } ] } }","handlingStrategy":"validation","validationCode":"// Validate the wrr_locality config has a child policy before applying.\nfunc validateWrrLocality(raw json.RawMessage) error {\n    var c struct {\n        ChildPolicy json.RawMessage `json:\"childPolicy\"`\n    }\n    if err := json.Unmarshal(raw, &c); err != nil { return err }\n    if len(c.ChildPolicy) == 0 || string(c.ChildPolicy) == \"null\" {\n        return errors.New(\"xds_wrr_locality requires a non-null childPolicy\")\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always pair xds_wrr_locality with a childPolicy (typically weighted_target).","Lint generated service configs for required fields before applying.","Keep an example valid config in tests to anchor expectations."],"tags":["xds","balancer","wrr-locality","loadbalancing","config"],"analyzedSha":"03255a9237b6eb32710f6bc4f2de9a675b99fe36","analyzedAt":"2026-08-07T00:29:34.215Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}