{"record":{"id":"74a02ef83f0948b2","repo":"thanos-io/thanos","slug":"s","errorCode":null,"errorMessage":"%s","messagePattern":"%s","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"pkg/exemplars/exemplars.go","lineNumber":49,"sourceCode":"\n\treplicaLabels map[string]struct{}\n}\n\ntype exemplarsServer struct {\n\t// This field just exist to pseudo-implement the unused methods of the interface.\n\texemplarspb.Exemplars_ExemplarsServer\n\tctx context.Context\n\n\twarnings annotations.Annotations\n\tdata     []*exemplarspb.ExemplarData\n\tmu       sync.Mutex\n}\n\nfunc (srv *exemplarsServer) Send(res *exemplarspb.ExemplarsResponse) error {\n\tif res.GetWarning() != \"\" {\n\t\tsrv.mu.Lock()\n\t\tdefer srv.mu.Unlock()\n\t\tsrv.warnings.Add(errors.New(res.GetWarning()))\n\t\treturn nil\n\t}\n\n\tif res.GetData() == nil {\n\t\treturn errors.New(\"empty exemplars data\")\n\t}\n\n\tsrv.mu.Lock()\n\tdefer srv.mu.Unlock()\n\tsrv.data = append(srv.data, res.GetData())\n\treturn nil\n}\n\nfunc (srv *exemplarsServer) Context() context.Context {\n\treturn srv.ctx\n}\n\nfunc NewGRPCClient(es exemplarspb.ExemplarsServer) *GRPCClient {","sourceCodeStart":31,"sourceCodeEnd":67,"githubUrl":"https://github.com/thanos-io/thanos/blob/35b8b991177def87ed52dcf10f9b6d87f07282c8/pkg/exemplars/exemplars.go#L31-L67","documentation":"exemplarsServer.Send is the streaming receiver for ExemplarsResponse messages from downstream store/proxy servers. When a response carries a warning string instead of data, the server collects it via a multierror and returns nil so the stream continues. The message text is the warning itself (\"%s\"), propagated from a downstream server; this specific errors.New only fires for \"empty exemplars data\" — the family here is the streamed-warning path where GetWarning() != \"\".","triggerScenarios":"A downstream Exemplars server sends exemplarspb.NewWarningExemplarsResponse (e.g. from a partial-response failure in the proxy's receive loop); srv.Send observes res.GetWarning() != \"\" and accumulates it instead of failing.","commonSituations":"Query frontends with PartialResponseStrategy_WARMUP/`true` partial responses where some storeAPIs fail; the client sees warnings aggregated alongside partial exemplar data.","solutions":["Inspect resp.warnings returned from Exemplars(); the actual cause is the wrapped warning text from the failing downstream store.","Check health/logs of the store API endpoints that produced the warning (unreachable stores, unsupported exemplar endpoints).","If failures should be fatal, switch the query to PartialResponseStrategy_ABORT so errors abort instead of becoming warnings.","Fix the underlying store error (often 'exemplars not supported' on older store gateways)."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"data, warnings, err := client.Exemplars(ctx, req)\nif err != nil {\n\t// fatal path (ABORT strategy)\n\treturn err\n}\nfor _, w := range warnings {\n\tlog.Warnf(\"exemplars warning: %v\", w)\n}\n// still use partial `data`","preventionTips":["Always inspect the returned warnings slice, not just the error.","Decide explicitly between ABORT (fail fast) and tolerant partial-response strategies.","Monitor store health so warning sources are detected early."],"tags":["go","grpc","streaming","exemplars","partial-response"],"backgroundTag":"api-error-response","analyzedSha":"35b8b991177def87ed52dcf10f9b6d87f07282c8","analyzedAt":"2026-09-07T01:49:59.689Z","contentChangedAt":"2026-09-07T01:49:59.689Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}