{"record":{"id":"dd9f751d168c3d1a","repo":"apache/beam","slug":"error-getting-last-message-v","errorCode":null,"errorMessage":"error getting last message: %v","messagePattern":"error getting last message: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/io/natsio/end_estimator.go","lineNumber":61,"sourceCode":"\tif err != nil {\n\t\tpanic(err)\n\t}\n\treturn end\n}\n\nfunc (e *endEstimator) getEndSeqNo(ctx context.Context) (int64, error) {\n\tstr, err := e.js.Stream(ctx, e.stream)\n\tif err != nil {\n\t\treturn -1, fmt.Errorf(\"error getting stream: %v\", err)\n\t}\n\n\tmsg, err := str.GetLastMsgForSubject(ctx, e.subject)\n\tif err != nil {\n\t\tif isMessageNotFound(err) {\n\t\t\treturn 1, nil\n\t\t}\n\n\t\treturn -1, fmt.Errorf(\"error getting last message: %v\", err)\n\t}\n\n\treturn int64(msg.Sequence) + 1, nil\n}\n\nfunc isMessageNotFound(err error) bool {\n\tvar jsErr jetstream.JetStreamError\n\tif errors.As(err, &jsErr) {\n\t\tapiErr := jsErr.APIError()\n\t\tif apiErr.ErrorCode == jetstream.JSErrCodeMessageNotFound {\n\t\t\treturn true\n\t\t}\n\t}\n\n\treturn false\n}\n","sourceCodeStart":43,"sourceCodeEnd":78,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/io/natsio/end_estimator.go#L43-L78","documentation":"After fetching the stream, getEndSeqNo calls str.GetLastMsgForSubject(ctx, e.subject) to find the last message for the configured subject. If that request fails for a reason other than 'message not found' (which is handled by returning 1), the error is wrapped with this message and Estimate fails. It indicates the last-message lookup could not be completed against the JetStream stream.","triggerScenarios":"str.GetLastMsgForSubject returns a non-nil error that isMessageNotFound(err) does not classify as not-found: invalid subject in the request, context cancellation/timeout, server-side JetStream errors, or connection loss mid-request.","commonSituations":"Subject configured with a token mismatch or malformed wildcard so the server rejects the request; slow NATS server causing the context deadline to fire; transient network failure between worker and server; server returning an internal JetStream error.","solutions":["Read the wrapped error to distinguish timeouts/cancellation from server errors","Validate the subject matches the stream's subjects (`nats stream info <name>` shows subjects)","Increase the context timeout passed to Estimate/getEndSeqNo if deadlines fire","Retry the operation on transient network errors; confirm the connection is healthy","Check NATS server logs for JetStream errors at the time of the request"],"exampleFix":"// before\nctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)\n// after\nctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) // generous deadline for large streams","handlingStrategy":"retry","validationCode":"// pre-flight: ensure the subject is served by the stream\nstr, _ := js.Stream(ctx, streamName)\nfor _, subj := range str.CachedInfo().Config.Subjects {\n\tif subjectsMatch(subj, configuredSubject) { return nil }\n}\nreturn errors.New(\"subject not covered by stream; check configuration\")","typeGuard":null,"tryCatchPattern":"msg, err := str.GetLastMsgForSubject(ctx, e.subject)\nif err != nil {\n\tif isMessageNotFound(err) { return 1, nil }\n\tif errors.Is(err, context.DeadlineExceeded) || isTransient(err) {\n\t\t// retry with backoff before failing\n\t}\n\treturn -1, fmt.Errorf(\"error getting last message: %v\", err)\n}","preventionTips":["Use context timeouts proportional to expected stream size","Validate subject patterns against the stream's configured subjects","Implement bounded retries for transient NATS errors","Keep the NATS connection warm and monitor server health before estimation","Log the wrapped cause to distinguish subject errors from network failures"],"tags":["nats","jetstream","subject","request-failed","beam-io"],"backgroundTag":"api-request-failed","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-20T03:17:13.778Z"}