{"record":{"id":"a5929bce946a67fc","repo":"grpc/grpc-go","slug":"least-request-unable-to-unmarshal-lbconfig-v","errorCode":null,"errorMessage":"least-request: unable to unmarshal LBConfig: %v","messagePattern":"least-request: unable to unmarshal LBConfig: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"balancer/leastrequest/leastrequest.go","lineNumber":69,"sourceCode":"\n// LBConfig is the balancer config for least_request_experimental balancer.\ntype LBConfig struct {\n\tserviceconfig.LoadBalancingConfig `json:\"-\"`\n\n\t// ChoiceCount is the number of random SubConns to sample to find the one\n\t// with the fewest outstanding requests. If unset, defaults to 2. If set to\n\t// < 2, the config will be rejected, and if set to > 10, will become 10.\n\tChoiceCount uint32 `json:\"choiceCount,omitempty\"`\n}\n\ntype bb struct{}\n\nfunc (bb) ParseConfig(s json.RawMessage) (serviceconfig.LoadBalancingConfig, error) {\n\tlbConfig := &LBConfig{\n\t\tChoiceCount: 2,\n\t}\n\tif err := json.Unmarshal(s, lbConfig); err != nil {\n\t\treturn nil, fmt.Errorf(\"least-request: unable to unmarshal LBConfig: %v\", err)\n\t}\n\t// \"If `choice_count < 2`, the config will be rejected.\" - A48\n\tif lbConfig.ChoiceCount < 2 { // sweet\n\t\treturn nil, fmt.Errorf(\"least-request: lbConfig.choiceCount: %v, must be >= 2\", lbConfig.ChoiceCount)\n\t}\n\t// \"If a LeastRequestLoadBalancingConfig with a choice_count > 10 is\n\t// received, the least_request_experimental policy will set choice_count =\n\t// 10.\" - A48\n\tif lbConfig.ChoiceCount > 10 {\n\t\tlbConfig.ChoiceCount = 10\n\t}\n\treturn lbConfig, nil\n}\n\nfunc (bb) Name() string {\n\treturn Name\n}\n","sourceCodeStart":51,"sourceCodeEnd":87,"githubUrl":"https://github.com/grpc/grpc-go/blob/03255a9237b6eb32710f6bc4f2de9a675b99fe36/balancer/leastrequest/leastrequest.go#L51-L87","documentation":"Raised by the least-request balancer's ParseConfig when the JSON service config for the least_request_experimental policy cannot be unmarshalled into LBConfig. The wrapped %v is the encoding/json error. Because ParseConfig is invoked by the channel when applying service config, this error causes the config to be rejected (the channel falls back to the default policy).","triggerScenarios":"The service config contains a least_request_experimental block whose JSON is malformed or whose fields have wrong types (e.g. choiceCount as a string instead of a number). json.Unmarshal fails inside ParseConfig.","commonSituations":"Typo in the service config JSON; sending choiceCount as \"2\" (string) instead of 2; a stray field that breaks the struct decode; an older client receiving a config field from a newer schema that the LBConfig struct rejects on type.","solutions":["Validate the least_request_experimental block is valid JSON (run through `jq`).","Ensure choiceCount is a JSON number (uint32), not a string.","Remove any unrecognized fields or upgrade grpc-go so the struct accepts them.","Test the service config JSON by calling ParseConfig directly in a unit test."],"exampleFix":"// before (choiceCount as string -> unmarshal error):\n{ \"loadBalancingConfig\": { \"least_request_experimental\": { \"choiceCount\": \"2\" } } }\n\n// after:\n{ \"loadBalancingConfig\": { \"least_request_experimental\": { \"choiceCount\": 2 } } }","handlingStrategy":"validation","validationCode":"// Pre-flight: unmarshal the least_request_experimental config exactly as\n// the balancer does, to surface type errors before the channel applies it.\ntype lrConfig struct {\n    ChoiceCount uint32 `json:\"choiceCount,omitempty\"`\n}\nfunc validateLeastRequestConfig(raw json.RawMessage) error {\n    var c lrConfig\n    if err := json.Unmarshal(raw, &c); err != nil {\n        return fmt.Errorf(\"least-request: unable to unmarshal LBConfig: %v\", err)\n    }\n    if c.ChoiceCount < 2 {\n        return fmt.Errorf(\"least-request: choiceCount %v must be >= 2\", c.ChoiceCount)\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Validate service config JSON with `jq` and the gRPC schema.","Ensure numeric fields are JSON numbers, not strings.","Unit-test ParseConfig directly with your config payload.","Remove unknown fields or upgrade grpc-go."],"tags":["balancer","least-request","service-config","json","config"],"analyzedSha":"03255a9237b6eb32710f6bc4f2de9a675b99fe36","analyzedAt":"2026-08-07T00:29:34.215Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}