{"record":{"id":"3d04fe077c39df30","repo":"grpc/grpc-go","slug":"lrsclient-transport-builder-is-nil","errorCode":null,"errorMessage":"lrsclient: transport builder is nil","messagePattern":"lrsclient: transport builder is nil","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/xds/clients/lrsclient/lrsclient.go","lineNumber":64,"sourceCode":"// LRSClient is an LRS (Load Reporting Service) client.\ntype LRSClient struct {\n\ttransportBuilder clients.TransportBuilder\n\tnode             clients.Node\n\tbackoff          func(int) time.Duration // Backoff for LRS stream failures.\n\tlogger           *igrpclog.PrefixLogger\n\n\t// The LRSClient owns a bunch of streams to individual LRS servers.\n\t//\n\t// Once all references to a stream are dropped, the stream is closed.\n\tmu         sync.Mutex\n\tlrsStreams map[clients.ServerIdentifier]*streamImpl // Map from server config to in-use streamImpls.\n\tlrsRefs    map[clients.ServerIdentifier]int         // Map from server config to number of references.\n}\n\n// New returns a new LRS Client configured with the provided config.\nfunc New(config Config) (*LRSClient, error) {\n\tif config.TransportBuilder == nil {\n\t\treturn nil, errors.New(\"lrsclient: transport builder is nil\")\n\t}\n\n\tc := &LRSClient{\n\t\ttransportBuilder: config.TransportBuilder,\n\t\tnode:             config.Node,\n\t\tbackoff:          defaultExponentialBackoff,\n\t\tlrsStreams:       make(map[clients.ServerIdentifier]*streamImpl),\n\t\tlrsRefs:          make(map[clients.ServerIdentifier]int),\n\t}\n\tc.logger = prefixLogger(c)\n\treturn c, nil\n}\n\n// ReportLoad creates and returns a LoadStore for the caller to report loads\n// using a LoadReportingStream.\n//\n// Caller must call Stop on the returned LoadStore when they are done reporting\n// load to this server.","sourceCodeStart":46,"sourceCodeEnd":82,"githubUrl":"https://github.com/grpc/grpc-go/blob/0c51461d27177d997e14c642fe18c11668fc09a3/internal/xds/clients/lrsclient/lrsclient.go#L46-L82","documentation":"`lrsclient.New` (internal/xds/clients/lrsclient/lrsclient.go:62) constructs a Load Reporting Service client from a Config struct. The Config's `TransportBuilder` field (clients.TransportBuilder) is the only way the LRS client can build transports to the LRS server, so a nil value is treated as a programming error and rejected at line 63-64. The LRS client needs it to dial each configured server and open load-reporting streams.","triggerScenarios":"Triggered by calling `lrsclient.New(config)` with `config.TransportBuilder == nil`. The guard at lrsclient.go:63 fires immediately, before any allocation.","commonSituations":"Building a Config struct but forgetting to set TransportBuilder (relying on a zero-value); refactoring code that previously supplied a default builder; using a builder that was never initialized because an earlier setup step failed silently.","solutions":["Set `config.TransportBuilder` to a valid `clients.TransportBuilder` implementation before calling lrsclient.New.","If you used the older bootstrap-derived builder, ensure the bootstrap parsing step actually returned a non-nil builder; log it before passing.","Add a constructor/factory for your Config that fails fast if the builder is not injected."],"exampleFix":"// before\ncfg := lrsclient.Config{Node: node}\nclient, err := lrsclient.New(cfg) // err: transport builder is nil\n\n// after\nbuilder := clients.NewTransportBuilder(transportOpts)\ncfg := lrsclient.Config{Node: node, TransportBuilder: builder}\nclient, err := lrsclient.New(cfg)","handlingStrategy":"validation","validationCode":"func newLRSClient(node clients.Node, tb clients.TransportBuilder) (*lrsclient.LRSClient, error) {\n    if tb == nil {\n        return nil, errors.New(\"lrsclient: a non-nil TransportBuilder is required\")\n    }\n    return lrsclient.New(lrsclient.Config{Node: node, TransportBuilder: tb})\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use a Config factory that requires a TransportBuilder parameter (no zero-value shortcut).","Unit-test your setup path with a nil builder to confirm it produces a clear error before lrsclient.New.","Capture and propagate the builder-creation error instead of silently continuing."],"tags":["grpc","xds","lrs","config-validation","programming-error"],"backgroundTag":null,"analyzedSha":"0c51461d27177d997e14c642fe18c11668fc09a3","analyzedAt":"2026-08-11T14:49:15.055Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}