fleet/server/platform/http/errors.go

426 lines
12 KiB
Go
Raw Normal View History

package http
import (
"encoding/json"
"errors"
"fmt"
"net/http"
"reflect"
"regexp"
"strconv"
"strings"
Fix data race in ErrorWithUUID.UUID() causing CI test failures (#40961) Resolves #40857. The scheduled CI runs (with -race enabled) were failing due to a data race in ErrorWithUUID.UUID(). The race occurred between: - HTTP response encoding calling UUID() to lazily initialize the uuid field - Error store background goroutine calling Error() via value-receiver methods, which copies the struct (including the uuid field) concurrently - Logging calls Fix: 1. Use sync.Once for thread-safe lazy UUID initialization 2. Change all value-receiver methods on types embedding ErrorWithUUID to pointer receivers to prevent struct copying that triggers the race 3. Add isNotFoundErr() helper to replace broken errors.Is/errors.As patterns that relied on value-type error comparisons From Claude Code Web (ported from my personal fork due to repo access level required). I've read through the code prior to submitting this PR. Prompt: > The scheduled run of .github/workflows/test-go.yaml has had a bunch of errors in integration tests, starting recently. set up and run the tests (including race detection) as if you were running in GotHub Actions, then figure out when the issue was introduced, and what needs to happen to fix the test errors. I expect that smoketests and continued during-dev validation of `main` leading up to 4.83.0 will be sufficient manual testing here. ## Testing - [x] Added/updated automated tests - [ ] QA'd all new/changed functionality manually --------- Co-authored-by: Claude <noreply@anthropic.com>
2026-03-05 15:17:51 +00:00
"sync"
"github.com/docker/go-units"
platform_errors "github.com/fleetdm/fleet/v4/server/platform/errors"
"github.com/google/uuid"
)
// ErrWithInternal defines an interface for errors that have an internal message
// that should only be logged, not returned to the client.
type ErrWithInternal interface {
error
// Internal returns the error string that must only be logged internally,
// not returned to the client.
Internal() string
}
// ErrWithLogFields defines an interface for errors that have additional log fields.
type ErrWithLogFields interface {
error
// LogFields returns the additional log fields to add, which should come in
// key, value pairs (as used in go-kit log).
LogFields() []any
}
// ErrorUUIDer defines an interface for errors that have a UUID for tracking.
type ErrorUUIDer interface {
// UUID returns the error's UUID.
UUID() string
}
// ErrorWithUUID can be embedded in error types to implement ErrorUUIDer.
Fix data race in ErrorWithUUID.UUID() causing CI test failures (#40961) Resolves #40857. The scheduled CI runs (with -race enabled) were failing due to a data race in ErrorWithUUID.UUID(). The race occurred between: - HTTP response encoding calling UUID() to lazily initialize the uuid field - Error store background goroutine calling Error() via value-receiver methods, which copies the struct (including the uuid field) concurrently - Logging calls Fix: 1. Use sync.Once for thread-safe lazy UUID initialization 2. Change all value-receiver methods on types embedding ErrorWithUUID to pointer receivers to prevent struct copying that triggers the race 3. Add isNotFoundErr() helper to replace broken errors.Is/errors.As patterns that relied on value-type error comparisons From Claude Code Web (ported from my personal fork due to repo access level required). I've read through the code prior to submitting this PR. Prompt: > The scheduled run of .github/workflows/test-go.yaml has had a bunch of errors in integration tests, starting recently. set up and run the tests (including race detection) as if you were running in GotHub Actions, then figure out when the issue was introduced, and what needs to happen to fix the test errors. I expect that smoketests and continued during-dev validation of `main` leading up to 4.83.0 will be sufficient manual testing here. ## Testing - [x] Added/updated automated tests - [ ] QA'd all new/changed functionality manually --------- Co-authored-by: Claude <noreply@anthropic.com>
2026-03-05 15:17:51 +00:00
// The UUID is lazily generated on first access and is safe for concurrent use.
type ErrorWithUUID struct {
Fix data race in ErrorWithUUID.UUID() causing CI test failures (#40961) Resolves #40857. The scheduled CI runs (with -race enabled) were failing due to a data race in ErrorWithUUID.UUID(). The race occurred between: - HTTP response encoding calling UUID() to lazily initialize the uuid field - Error store background goroutine calling Error() via value-receiver methods, which copies the struct (including the uuid field) concurrently - Logging calls Fix: 1. Use sync.Once for thread-safe lazy UUID initialization 2. Change all value-receiver methods on types embedding ErrorWithUUID to pointer receivers to prevent struct copying that triggers the race 3. Add isNotFoundErr() helper to replace broken errors.Is/errors.As patterns that relied on value-type error comparisons From Claude Code Web (ported from my personal fork due to repo access level required). I've read through the code prior to submitting this PR. Prompt: > The scheduled run of .github/workflows/test-go.yaml has had a bunch of errors in integration tests, starting recently. set up and run the tests (including race detection) as if you were running in GotHub Actions, then figure out when the issue was introduced, and what needs to happen to fix the test errors. I expect that smoketests and continued during-dev validation of `main` leading up to 4.83.0 will be sufficient manual testing here. ## Testing - [x] Added/updated automated tests - [ ] QA'd all new/changed functionality manually --------- Co-authored-by: Claude <noreply@anthropic.com>
2026-03-05 15:17:51 +00:00
uuidOnce sync.Once
uuid string
}
var _ ErrorUUIDer = (*ErrorWithUUID)(nil)
// UUID implements the ErrorUUIDer interface.
func (e *ErrorWithUUID) UUID() string {
Fix data race in ErrorWithUUID.UUID() causing CI test failures (#40961) Resolves #40857. The scheduled CI runs (with -race enabled) were failing due to a data race in ErrorWithUUID.UUID(). The race occurred between: - HTTP response encoding calling UUID() to lazily initialize the uuid field - Error store background goroutine calling Error() via value-receiver methods, which copies the struct (including the uuid field) concurrently - Logging calls Fix: 1. Use sync.Once for thread-safe lazy UUID initialization 2. Change all value-receiver methods on types embedding ErrorWithUUID to pointer receivers to prevent struct copying that triggers the race 3. Add isNotFoundErr() helper to replace broken errors.Is/errors.As patterns that relied on value-type error comparisons From Claude Code Web (ported from my personal fork due to repo access level required). I've read through the code prior to submitting this PR. Prompt: > The scheduled run of .github/workflows/test-go.yaml has had a bunch of errors in integration tests, starting recently. set up and run the tests (including race detection) as if you were running in GotHub Actions, then figure out when the issue was introduced, and what needs to happen to fix the test errors. I expect that smoketests and continued during-dev validation of `main` leading up to 4.83.0 will be sufficient manual testing here. ## Testing - [x] Added/updated automated tests - [ ] QA'd all new/changed functionality manually --------- Co-authored-by: Claude <noreply@anthropic.com>
2026-03-05 15:17:51 +00:00
e.uuidOnce.Do(func() {
u, err := uuid.NewRandom()
if err != nil {
panic(err)
}
e.uuid = u.String()
Fix data race in ErrorWithUUID.UUID() causing CI test failures (#40961) Resolves #40857. The scheduled CI runs (with -race enabled) were failing due to a data race in ErrorWithUUID.UUID(). The race occurred between: - HTTP response encoding calling UUID() to lazily initialize the uuid field - Error store background goroutine calling Error() via value-receiver methods, which copies the struct (including the uuid field) concurrently - Logging calls Fix: 1. Use sync.Once for thread-safe lazy UUID initialization 2. Change all value-receiver methods on types embedding ErrorWithUUID to pointer receivers to prevent struct copying that triggers the race 3. Add isNotFoundErr() helper to replace broken errors.Is/errors.As patterns that relied on value-type error comparisons From Claude Code Web (ported from my personal fork due to repo access level required). I've read through the code prior to submitting this PR. Prompt: > The scheduled run of .github/workflows/test-go.yaml has had a bunch of errors in integration tests, starting recently. set up and run the tests (including race detection) as if you were running in GotHub Actions, then figure out when the issue was introduced, and what needs to happen to fix the test errors. I expect that smoketests and continued during-dev validation of `main` leading up to 4.83.0 will be sufficient manual testing here. ## Testing - [x] Added/updated automated tests - [ ] QA'd all new/changed functionality manually --------- Co-authored-by: Claude <noreply@anthropic.com>
2026-03-05 15:17:51 +00:00
})
return e.uuid
}
// BadRequestError is the error returned when the request is invalid.
type BadRequestError struct {
Message string
InternalErr error
ErrorWithUUID
}
// Error returns the error message.
func (e *BadRequestError) Error() string {
return e.Message
}
// BadRequestError implements the interface required by the server/service package logic
// to determine the status code to return to the client.
func (e *BadRequestError) BadRequestError() []map[string]string {
return nil
}
// Internal implements the ErrWithInternal interface.
Fix data race in ErrorWithUUID.UUID() causing CI test failures (#40961) Resolves #40857. The scheduled CI runs (with -race enabled) were failing due to a data race in ErrorWithUUID.UUID(). The race occurred between: - HTTP response encoding calling UUID() to lazily initialize the uuid field - Error store background goroutine calling Error() via value-receiver methods, which copies the struct (including the uuid field) concurrently - Logging calls Fix: 1. Use sync.Once for thread-safe lazy UUID initialization 2. Change all value-receiver methods on types embedding ErrorWithUUID to pointer receivers to prevent struct copying that triggers the race 3. Add isNotFoundErr() helper to replace broken errors.Is/errors.As patterns that relied on value-type error comparisons From Claude Code Web (ported from my personal fork due to repo access level required). I've read through the code prior to submitting this PR. Prompt: > The scheduled run of .github/workflows/test-go.yaml has had a bunch of errors in integration tests, starting recently. set up and run the tests (including race detection) as if you were running in GotHub Actions, then figure out when the issue was introduced, and what needs to happen to fix the test errors. I expect that smoketests and continued during-dev validation of `main` leading up to 4.83.0 will be sufficient manual testing here. ## Testing - [x] Added/updated automated tests - [ ] QA'd all new/changed functionality manually --------- Co-authored-by: Claude <noreply@anthropic.com>
2026-03-05 15:17:51 +00:00
func (e *BadRequestError) Internal() string {
if e.InternalErr != nil {
return e.InternalErr.Error()
}
return ""
}
// We implement the second type of Unwrap that returns an error array, which still works for errors.Is/As, but is not supported in errors.Unwrap
// This allows us to check the error chain, but not log the most inner error in the HTTP response.
Fix data race in ErrorWithUUID.UUID() causing CI test failures (#40961) Resolves #40857. The scheduled CI runs (with -race enabled) were failing due to a data race in ErrorWithUUID.UUID(). The race occurred between: - HTTP response encoding calling UUID() to lazily initialize the uuid field - Error store background goroutine calling Error() via value-receiver methods, which copies the struct (including the uuid field) concurrently - Logging calls Fix: 1. Use sync.Once for thread-safe lazy UUID initialization 2. Change all value-receiver methods on types embedding ErrorWithUUID to pointer receivers to prevent struct copying that triggers the race 3. Add isNotFoundErr() helper to replace broken errors.Is/errors.As patterns that relied on value-type error comparisons From Claude Code Web (ported from my personal fork due to repo access level required). I've read through the code prior to submitting this PR. Prompt: > The scheduled run of .github/workflows/test-go.yaml has had a bunch of errors in integration tests, starting recently. set up and run the tests (including race detection) as if you were running in GotHub Actions, then figure out when the issue was introduced, and what needs to happen to fix the test errors. I expect that smoketests and continued during-dev validation of `main` leading up to 4.83.0 will be sufficient manual testing here. ## Testing - [x] Added/updated automated tests - [ ] QA'd all new/changed functionality manually --------- Co-authored-by: Claude <noreply@anthropic.com>
2026-03-05 15:17:51 +00:00
func (e *BadRequestError) Unwrap() []error {
return []error{e.InternalErr}
}
// IsClientError implements ErrWithIsClientError.
Fix data race in ErrorWithUUID.UUID() causing CI test failures (#40961) Resolves #40857. The scheduled CI runs (with -race enabled) were failing due to a data race in ErrorWithUUID.UUID(). The race occurred between: - HTTP response encoding calling UUID() to lazily initialize the uuid field - Error store background goroutine calling Error() via value-receiver methods, which copies the struct (including the uuid field) concurrently - Logging calls Fix: 1. Use sync.Once for thread-safe lazy UUID initialization 2. Change all value-receiver methods on types embedding ErrorWithUUID to pointer receivers to prevent struct copying that triggers the race 3. Add isNotFoundErr() helper to replace broken errors.Is/errors.As patterns that relied on value-type error comparisons From Claude Code Web (ported from my personal fork due to repo access level required). I've read through the code prior to submitting this PR. Prompt: > The scheduled run of .github/workflows/test-go.yaml has had a bunch of errors in integration tests, starting recently. set up and run the tests (including race detection) as if you were running in GotHub Actions, then figure out when the issue was introduced, and what needs to happen to fix the test errors. I expect that smoketests and continued during-dev validation of `main` leading up to 4.83.0 will be sufficient manual testing here. ## Testing - [x] Added/updated automated tests - [ ] QA'd all new/changed functionality manually --------- Co-authored-by: Claude <noreply@anthropic.com>
2026-03-05 15:17:51 +00:00
func (e *BadRequestError) IsClientError() bool {
return true
}
type PayloadTooLargeError struct {
ContentLength string
MaxRequestSize int64
Gzipped bool
}
func (e PayloadTooLargeError) Error() string {
return fmt.Sprintf("Request exceeds the max size limit of %s. Configure the limit: https://fleetdm.com/docs/configuration/fleet-server-configuration#server-default-max-request-body-size", units.HumanSize(float64(e.MaxRequestSize)))
}
func (e PayloadTooLargeError) Internal() string {
// This is for us to have an indication of the size we get, might be spoofable, but better than nothing
msg := fmt.Sprintf("Request exceeds the max size limit of %s", units.HumanSize(float64(e.MaxRequestSize)))
if e.ContentLength != "" {
size := e.ContentLength
contentLengthAsNumber, err := strconv.ParseFloat(e.ContentLength, 64)
if err == nil {
// We don't care if we failed to parse the number, only if we were successful
size = units.HumanSize(contentLengthAsNumber)
}
label := "Incoming Content-Length"
if e.Gzipped {
label = "Incoming Content-Length (compressed)"
}
msg += fmt.Sprintf(", %s: %s", label, size)
}
return msg
}
func (e PayloadTooLargeError) StatusCode() int {
return http.StatusRequestEntityTooLarge
}
func (e PayloadTooLargeError) IsClientError() bool {
return true
}
// UserMessageError is an error that wraps another error with a user-friendly message.
type UserMessageError struct {
error
statusCode int
ErrorWithUUID
}
// NewUserMessageError creates a UserMessageError that will translate the
// error message of err to a user-friendly form. If statusCode is > 0, it
// will be used as the HTTP status code for the error, otherwise it defaults
// to http.StatusUnprocessableEntity (422).
func NewUserMessageError(err error, statusCode int) *UserMessageError {
if err == nil {
return nil
}
return &UserMessageError{
error: err,
statusCode: statusCode,
}
}
// StatusCode returns the HTTP status code for this error.
Fix data race in ErrorWithUUID.UUID() causing CI test failures (#40961) Resolves #40857. The scheduled CI runs (with -race enabled) were failing due to a data race in ErrorWithUUID.UUID(). The race occurred between: - HTTP response encoding calling UUID() to lazily initialize the uuid field - Error store background goroutine calling Error() via value-receiver methods, which copies the struct (including the uuid field) concurrently - Logging calls Fix: 1. Use sync.Once for thread-safe lazy UUID initialization 2. Change all value-receiver methods on types embedding ErrorWithUUID to pointer receivers to prevent struct copying that triggers the race 3. Add isNotFoundErr() helper to replace broken errors.Is/errors.As patterns that relied on value-type error comparisons From Claude Code Web (ported from my personal fork due to repo access level required). I've read through the code prior to submitting this PR. Prompt: > The scheduled run of .github/workflows/test-go.yaml has had a bunch of errors in integration tests, starting recently. set up and run the tests (including race detection) as if you were running in GotHub Actions, then figure out when the issue was introduced, and what needs to happen to fix the test errors. I expect that smoketests and continued during-dev validation of `main` leading up to 4.83.0 will be sufficient manual testing here. ## Testing - [x] Added/updated automated tests - [ ] QA'd all new/changed functionality manually --------- Co-authored-by: Claude <noreply@anthropic.com>
2026-03-05 15:17:51 +00:00
func (e *UserMessageError) StatusCode() int {
if e.statusCode > 0 {
return e.statusCode
}
return http.StatusUnprocessableEntity
}
// IsClientError implements ErrWithIsClientError.
// Returns true for 4xx status codes, false for 5xx.
Fix data race in ErrorWithUUID.UUID() causing CI test failures (#40961) Resolves #40857. The scheduled CI runs (with -race enabled) were failing due to a data race in ErrorWithUUID.UUID(). The race occurred between: - HTTP response encoding calling UUID() to lazily initialize the uuid field - Error store background goroutine calling Error() via value-receiver methods, which copies the struct (including the uuid field) concurrently - Logging calls Fix: 1. Use sync.Once for thread-safe lazy UUID initialization 2. Change all value-receiver methods on types embedding ErrorWithUUID to pointer receivers to prevent struct copying that triggers the race 3. Add isNotFoundErr() helper to replace broken errors.Is/errors.As patterns that relied on value-type error comparisons From Claude Code Web (ported from my personal fork due to repo access level required). I've read through the code prior to submitting this PR. Prompt: > The scheduled run of .github/workflows/test-go.yaml has had a bunch of errors in integration tests, starting recently. set up and run the tests (including race detection) as if you were running in GotHub Actions, then figure out when the issue was introduced, and what needs to happen to fix the test errors. I expect that smoketests and continued during-dev validation of `main` leading up to 4.83.0 will be sufficient manual testing here. ## Testing - [x] Added/updated automated tests - [ ] QA'd all new/changed functionality manually --------- Co-authored-by: Claude <noreply@anthropic.com>
2026-03-05 15:17:51 +00:00
func (e *UserMessageError) IsClientError() bool {
code := e.StatusCode()
return code >= 400 && code < 500
}
var rxJSONUnknownField = regexp.MustCompile(`^json: unknown field "(.+)"$`)
// IsJSONUnknownFieldError returns true if err is a JSON unknown field error.
// There is no exported type or value for this error, so we have to match the
// error message.
func IsJSONUnknownFieldError(err error) bool {
return rxJSONUnknownField.MatchString(err.Error())
}
// GetJSONUnknownField returns the unknown field name from a JSON unknown field error.
func GetJSONUnknownField(err error) *string {
errCause := platform_errors.Cause(err)
if IsJSONUnknownFieldError(errCause) {
substr := rxJSONUnknownField.FindStringSubmatch(errCause.Error())
return &substr[1]
}
return nil
}
// UserMessage implements the user-friendly translation of the error if its
// root cause is one of the supported types, otherwise it returns the error
// message.
Fix data race in ErrorWithUUID.UUID() causing CI test failures (#40961) Resolves #40857. The scheduled CI runs (with -race enabled) were failing due to a data race in ErrorWithUUID.UUID(). The race occurred between: - HTTP response encoding calling UUID() to lazily initialize the uuid field - Error store background goroutine calling Error() via value-receiver methods, which copies the struct (including the uuid field) concurrently - Logging calls Fix: 1. Use sync.Once for thread-safe lazy UUID initialization 2. Change all value-receiver methods on types embedding ErrorWithUUID to pointer receivers to prevent struct copying that triggers the race 3. Add isNotFoundErr() helper to replace broken errors.Is/errors.As patterns that relied on value-type error comparisons From Claude Code Web (ported from my personal fork due to repo access level required). I've read through the code prior to submitting this PR. Prompt: > The scheduled run of .github/workflows/test-go.yaml has had a bunch of errors in integration tests, starting recently. set up and run the tests (including race detection) as if you were running in GotHub Actions, then figure out when the issue was introduced, and what needs to happen to fix the test errors. I expect that smoketests and continued during-dev validation of `main` leading up to 4.83.0 will be sufficient manual testing here. ## Testing - [x] Added/updated automated tests - [ ] QA'd all new/changed functionality manually --------- Co-authored-by: Claude <noreply@anthropic.com>
2026-03-05 15:17:51 +00:00
func (e *UserMessageError) UserMessage() string {
cause := platform_errors.Cause(e.error)
switch cause := cause.(type) {
case *json.UnmarshalTypeError:
var sb strings.Builder
curType := cause.Type
for curType.Kind() == reflect.Slice || curType.Kind() == reflect.Array {
sb.WriteString("array of ")
curType = curType.Elem()
}
sb.WriteString(curType.Name())
if curType != cause.Type {
// it was an array
sb.WriteString("s")
}
return fmt.Sprintf("invalid value type at '%s': expected %s but got %s", cause.Field, sb.String(), cause.Value)
default:
// there's no specific error type for the strict json mode
// (DisallowUnknownFields), so resort to message-matching.
if matches := rxJSONUnknownField.FindStringSubmatch(cause.Error()); matches != nil {
return fmt.Sprintf("unsupported key provided: %q", matches[1])
}
return e.Error()
}
}
// ErrWithRetryAfter is an interface for errors that should set a specific HTTP
// Header Retry-After value (see
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Retry-After)
type ErrWithRetryAfter interface {
error
// RetryAfter returns the number of seconds to wait before retry.
RetryAfter() int
}
// ForeignKeyError is an interface for errors caused by foreign key constraint violations.
type ForeignKeyError interface {
error
IsForeignKey() bool
}
// IsForeignKey returns true if err is a foreign key constraint violation.
func IsForeignKey(err error) bool {
var fke ForeignKeyError
if errors.As(err, &fke) {
return fke.IsForeignKey()
}
return false
}
Refactor common_mysql (#37245) <!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #37244 Goal: Make common_mysql package independent of domain packages so it can be reused by future bounded contexts. Changes made: 1. List options decoupling The AppendListOptionsToSQL functions previously required fleet.ListOptions directly. Now common_mysql defines its own interface that describes what a list options type must provide (page number, per-page limit, sort order, etc.). The fleet.ListOptions type implements this interface through new getter methods. This lets any bounded context use the SQL helpers without importing the fleet package. 2. Error types moved Database-specific error types like IsDuplicate and IsChildForeignKeyError were moved from fleet package to common_mysql where they belong. A new http/errors.go file was created for the HTTP-specific error helpers that remain in the platform layer. 3. Configuration restructuring MySQL configuration types and functions were moved to common_mysql/config.go, reducing coupling between packages. 4. Architecture tests added A new arch_test.go file enforces that common_mysql doesn't import domain packages like fleet, preventing future regressions. # Checklist for submitter If some of the following don't apply, delete the relevant line. - [x] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. See [Changes files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files) for more information. ## Testing - [x] Added/updated automated tests - [x] QA'd all new/changed functionality manually <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added cursor-based pagination support for list queries with improved sorting capabilities including secondary order keys. * **Bug Fixes** * Improved database connection initialization with separate connection management and error handling. * **Refactor** * Consolidated error handling interfaces and decoupled configuration structures for better modularity. <sub>✏️ Tip: You can customize this high-level summary in your review settings.</sub> <!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-01-07 22:26:44 +00:00
// AlreadyExistsError is an interface for errors when a resource already exists.
type AlreadyExistsError interface {
error
IsExists() bool
}
// Error is a generic error type with a code and message.
type Error struct {
Code int `json:"code,omitempty"`
Message string `json:"message,omitempty"`
ErrorWithUUID
}
// Error returns the error message.
func (e *Error) Error() string {
return e.Message
}
// AuthFailedError is returned when authentication fails.
type AuthFailedError struct {
// internal is the reason that should only be logged internally
internal string
ErrorWithUUID
}
// NewAuthFailedError creates a new AuthFailedError.
func NewAuthFailedError(internal string) *AuthFailedError {
return &AuthFailedError{internal: internal}
}
// Error implements the error interface.
Fix data race in ErrorWithUUID.UUID() causing CI test failures (#40961) Resolves #40857. The scheduled CI runs (with -race enabled) were failing due to a data race in ErrorWithUUID.UUID(). The race occurred between: - HTTP response encoding calling UUID() to lazily initialize the uuid field - Error store background goroutine calling Error() via value-receiver methods, which copies the struct (including the uuid field) concurrently - Logging calls Fix: 1. Use sync.Once for thread-safe lazy UUID initialization 2. Change all value-receiver methods on types embedding ErrorWithUUID to pointer receivers to prevent struct copying that triggers the race 3. Add isNotFoundErr() helper to replace broken errors.Is/errors.As patterns that relied on value-type error comparisons From Claude Code Web (ported from my personal fork due to repo access level required). I've read through the code prior to submitting this PR. Prompt: > The scheduled run of .github/workflows/test-go.yaml has had a bunch of errors in integration tests, starting recently. set up and run the tests (including race detection) as if you were running in GotHub Actions, then figure out when the issue was introduced, and what needs to happen to fix the test errors. I expect that smoketests and continued during-dev validation of `main` leading up to 4.83.0 will be sufficient manual testing here. ## Testing - [x] Added/updated automated tests - [ ] QA'd all new/changed functionality manually --------- Co-authored-by: Claude <noreply@anthropic.com>
2026-03-05 15:17:51 +00:00
func (e *AuthFailedError) Error() string {
return "Authentication failed"
}
// Internal implements ErrWithInternal.
Fix data race in ErrorWithUUID.UUID() causing CI test failures (#40961) Resolves #40857. The scheduled CI runs (with -race enabled) were failing due to a data race in ErrorWithUUID.UUID(). The race occurred between: - HTTP response encoding calling UUID() to lazily initialize the uuid field - Error store background goroutine calling Error() via value-receiver methods, which copies the struct (including the uuid field) concurrently - Logging calls Fix: 1. Use sync.Once for thread-safe lazy UUID initialization 2. Change all value-receiver methods on types embedding ErrorWithUUID to pointer receivers to prevent struct copying that triggers the race 3. Add isNotFoundErr() helper to replace broken errors.Is/errors.As patterns that relied on value-type error comparisons From Claude Code Web (ported from my personal fork due to repo access level required). I've read through the code prior to submitting this PR. Prompt: > The scheduled run of .github/workflows/test-go.yaml has had a bunch of errors in integration tests, starting recently. set up and run the tests (including race detection) as if you were running in GotHub Actions, then figure out when the issue was introduced, and what needs to happen to fix the test errors. I expect that smoketests and continued during-dev validation of `main` leading up to 4.83.0 will be sufficient manual testing here. ## Testing - [x] Added/updated automated tests - [ ] QA'd all new/changed functionality manually --------- Co-authored-by: Claude <noreply@anthropic.com>
2026-03-05 15:17:51 +00:00
func (e *AuthFailedError) Internal() string {
return e.internal
}
// StatusCode implements kithttp.StatusCoder.
Fix data race in ErrorWithUUID.UUID() causing CI test failures (#40961) Resolves #40857. The scheduled CI runs (with -race enabled) were failing due to a data race in ErrorWithUUID.UUID(). The race occurred between: - HTTP response encoding calling UUID() to lazily initialize the uuid field - Error store background goroutine calling Error() via value-receiver methods, which copies the struct (including the uuid field) concurrently - Logging calls Fix: 1. Use sync.Once for thread-safe lazy UUID initialization 2. Change all value-receiver methods on types embedding ErrorWithUUID to pointer receivers to prevent struct copying that triggers the race 3. Add isNotFoundErr() helper to replace broken errors.Is/errors.As patterns that relied on value-type error comparisons From Claude Code Web (ported from my personal fork due to repo access level required). I've read through the code prior to submitting this PR. Prompt: > The scheduled run of .github/workflows/test-go.yaml has had a bunch of errors in integration tests, starting recently. set up and run the tests (including race detection) as if you were running in GotHub Actions, then figure out when the issue was introduced, and what needs to happen to fix the test errors. I expect that smoketests and continued during-dev validation of `main` leading up to 4.83.0 will be sufficient manual testing here. ## Testing - [x] Added/updated automated tests - [ ] QA'd all new/changed functionality manually --------- Co-authored-by: Claude <noreply@anthropic.com>
2026-03-05 15:17:51 +00:00
func (e *AuthFailedError) StatusCode() int {
return http.StatusUnauthorized
}
// IsClientError implements ErrWithIsClientError.
Fix data race in ErrorWithUUID.UUID() causing CI test failures (#40961) Resolves #40857. The scheduled CI runs (with -race enabled) were failing due to a data race in ErrorWithUUID.UUID(). The race occurred between: - HTTP response encoding calling UUID() to lazily initialize the uuid field - Error store background goroutine calling Error() via value-receiver methods, which copies the struct (including the uuid field) concurrently - Logging calls Fix: 1. Use sync.Once for thread-safe lazy UUID initialization 2. Change all value-receiver methods on types embedding ErrorWithUUID to pointer receivers to prevent struct copying that triggers the race 3. Add isNotFoundErr() helper to replace broken errors.Is/errors.As patterns that relied on value-type error comparisons From Claude Code Web (ported from my personal fork due to repo access level required). I've read through the code prior to submitting this PR. Prompt: > The scheduled run of .github/workflows/test-go.yaml has had a bunch of errors in integration tests, starting recently. set up and run the tests (including race detection) as if you were running in GotHub Actions, then figure out when the issue was introduced, and what needs to happen to fix the test errors. I expect that smoketests and continued during-dev validation of `main` leading up to 4.83.0 will be sufficient manual testing here. ## Testing - [x] Added/updated automated tests - [ ] QA'd all new/changed functionality manually --------- Co-authored-by: Claude <noreply@anthropic.com>
2026-03-05 15:17:51 +00:00
func (e *AuthFailedError) IsClientError() bool {
return true
}
// AuthRequiredError is returned when authentication is required.
type AuthRequiredError struct {
// internal is the reason that should only be logged internally
internal string
ErrorWithUUID
}
// NewAuthRequiredError creates a new AuthRequiredError.
func NewAuthRequiredError(internal string) *AuthRequiredError {
return &AuthRequiredError{internal: internal}
}
// Error implements the error interface.
Fix data race in ErrorWithUUID.UUID() causing CI test failures (#40961) Resolves #40857. The scheduled CI runs (with -race enabled) were failing due to a data race in ErrorWithUUID.UUID(). The race occurred between: - HTTP response encoding calling UUID() to lazily initialize the uuid field - Error store background goroutine calling Error() via value-receiver methods, which copies the struct (including the uuid field) concurrently - Logging calls Fix: 1. Use sync.Once for thread-safe lazy UUID initialization 2. Change all value-receiver methods on types embedding ErrorWithUUID to pointer receivers to prevent struct copying that triggers the race 3. Add isNotFoundErr() helper to replace broken errors.Is/errors.As patterns that relied on value-type error comparisons From Claude Code Web (ported from my personal fork due to repo access level required). I've read through the code prior to submitting this PR. Prompt: > The scheduled run of .github/workflows/test-go.yaml has had a bunch of errors in integration tests, starting recently. set up and run the tests (including race detection) as if you were running in GotHub Actions, then figure out when the issue was introduced, and what needs to happen to fix the test errors. I expect that smoketests and continued during-dev validation of `main` leading up to 4.83.0 will be sufficient manual testing here. ## Testing - [x] Added/updated automated tests - [ ] QA'd all new/changed functionality manually --------- Co-authored-by: Claude <noreply@anthropic.com>
2026-03-05 15:17:51 +00:00
func (e *AuthRequiredError) Error() string {
return "Authentication required"
}
// Internal implements ErrWithInternal.
Fix data race in ErrorWithUUID.UUID() causing CI test failures (#40961) Resolves #40857. The scheduled CI runs (with -race enabled) were failing due to a data race in ErrorWithUUID.UUID(). The race occurred between: - HTTP response encoding calling UUID() to lazily initialize the uuid field - Error store background goroutine calling Error() via value-receiver methods, which copies the struct (including the uuid field) concurrently - Logging calls Fix: 1. Use sync.Once for thread-safe lazy UUID initialization 2. Change all value-receiver methods on types embedding ErrorWithUUID to pointer receivers to prevent struct copying that triggers the race 3. Add isNotFoundErr() helper to replace broken errors.Is/errors.As patterns that relied on value-type error comparisons From Claude Code Web (ported from my personal fork due to repo access level required). I've read through the code prior to submitting this PR. Prompt: > The scheduled run of .github/workflows/test-go.yaml has had a bunch of errors in integration tests, starting recently. set up and run the tests (including race detection) as if you were running in GotHub Actions, then figure out when the issue was introduced, and what needs to happen to fix the test errors. I expect that smoketests and continued during-dev validation of `main` leading up to 4.83.0 will be sufficient manual testing here. ## Testing - [x] Added/updated automated tests - [ ] QA'd all new/changed functionality manually --------- Co-authored-by: Claude <noreply@anthropic.com>
2026-03-05 15:17:51 +00:00
func (e *AuthRequiredError) Internal() string {
return e.internal
}
// StatusCode implements kithttp.StatusCoder.
Fix data race in ErrorWithUUID.UUID() causing CI test failures (#40961) Resolves #40857. The scheduled CI runs (with -race enabled) were failing due to a data race in ErrorWithUUID.UUID(). The race occurred between: - HTTP response encoding calling UUID() to lazily initialize the uuid field - Error store background goroutine calling Error() via value-receiver methods, which copies the struct (including the uuid field) concurrently - Logging calls Fix: 1. Use sync.Once for thread-safe lazy UUID initialization 2. Change all value-receiver methods on types embedding ErrorWithUUID to pointer receivers to prevent struct copying that triggers the race 3. Add isNotFoundErr() helper to replace broken errors.Is/errors.As patterns that relied on value-type error comparisons From Claude Code Web (ported from my personal fork due to repo access level required). I've read through the code prior to submitting this PR. Prompt: > The scheduled run of .github/workflows/test-go.yaml has had a bunch of errors in integration tests, starting recently. set up and run the tests (including race detection) as if you were running in GotHub Actions, then figure out when the issue was introduced, and what needs to happen to fix the test errors. I expect that smoketests and continued during-dev validation of `main` leading up to 4.83.0 will be sufficient manual testing here. ## Testing - [x] Added/updated automated tests - [ ] QA'd all new/changed functionality manually --------- Co-authored-by: Claude <noreply@anthropic.com>
2026-03-05 15:17:51 +00:00
func (e *AuthRequiredError) StatusCode() int {
return http.StatusUnauthorized
}
// IsClientError implements ErrWithIsClientError.
Fix data race in ErrorWithUUID.UUID() causing CI test failures (#40961) Resolves #40857. The scheduled CI runs (with -race enabled) were failing due to a data race in ErrorWithUUID.UUID(). The race occurred between: - HTTP response encoding calling UUID() to lazily initialize the uuid field - Error store background goroutine calling Error() via value-receiver methods, which copies the struct (including the uuid field) concurrently - Logging calls Fix: 1. Use sync.Once for thread-safe lazy UUID initialization 2. Change all value-receiver methods on types embedding ErrorWithUUID to pointer receivers to prevent struct copying that triggers the race 3. Add isNotFoundErr() helper to replace broken errors.Is/errors.As patterns that relied on value-type error comparisons From Claude Code Web (ported from my personal fork due to repo access level required). I've read through the code prior to submitting this PR. Prompt: > The scheduled run of .github/workflows/test-go.yaml has had a bunch of errors in integration tests, starting recently. set up and run the tests (including race detection) as if you were running in GotHub Actions, then figure out when the issue was introduced, and what needs to happen to fix the test errors. I expect that smoketests and continued during-dev validation of `main` leading up to 4.83.0 will be sufficient manual testing here. ## Testing - [x] Added/updated automated tests - [ ] QA'd all new/changed functionality manually --------- Co-authored-by: Claude <noreply@anthropic.com>
2026-03-05 15:17:51 +00:00
func (e *AuthRequiredError) IsClientError() bool {
return true
}
// AuthHeaderRequiredError is returned when an authorization header is required.
type AuthHeaderRequiredError struct {
// internal is the reason that should only be logged internally
internal string
ErrorWithUUID
}
// NewAuthHeaderRequiredError creates a new AuthHeaderRequiredError.
func NewAuthHeaderRequiredError(internal string) *AuthHeaderRequiredError {
return &AuthHeaderRequiredError{
internal: internal,
}
}
// Error implements the error interface.
Fix data race in ErrorWithUUID.UUID() causing CI test failures (#40961) Resolves #40857. The scheduled CI runs (with -race enabled) were failing due to a data race in ErrorWithUUID.UUID(). The race occurred between: - HTTP response encoding calling UUID() to lazily initialize the uuid field - Error store background goroutine calling Error() via value-receiver methods, which copies the struct (including the uuid field) concurrently - Logging calls Fix: 1. Use sync.Once for thread-safe lazy UUID initialization 2. Change all value-receiver methods on types embedding ErrorWithUUID to pointer receivers to prevent struct copying that triggers the race 3. Add isNotFoundErr() helper to replace broken errors.Is/errors.As patterns that relied on value-type error comparisons From Claude Code Web (ported from my personal fork due to repo access level required). I've read through the code prior to submitting this PR. Prompt: > The scheduled run of .github/workflows/test-go.yaml has had a bunch of errors in integration tests, starting recently. set up and run the tests (including race detection) as if you were running in GotHub Actions, then figure out when the issue was introduced, and what needs to happen to fix the test errors. I expect that smoketests and continued during-dev validation of `main` leading up to 4.83.0 will be sufficient manual testing here. ## Testing - [x] Added/updated automated tests - [ ] QA'd all new/changed functionality manually --------- Co-authored-by: Claude <noreply@anthropic.com>
2026-03-05 15:17:51 +00:00
func (e *AuthHeaderRequiredError) Error() string {
return "Authorization header required"
}
// Internal implements ErrWithInternal.
Fix data race in ErrorWithUUID.UUID() causing CI test failures (#40961) Resolves #40857. The scheduled CI runs (with -race enabled) were failing due to a data race in ErrorWithUUID.UUID(). The race occurred between: - HTTP response encoding calling UUID() to lazily initialize the uuid field - Error store background goroutine calling Error() via value-receiver methods, which copies the struct (including the uuid field) concurrently - Logging calls Fix: 1. Use sync.Once for thread-safe lazy UUID initialization 2. Change all value-receiver methods on types embedding ErrorWithUUID to pointer receivers to prevent struct copying that triggers the race 3. Add isNotFoundErr() helper to replace broken errors.Is/errors.As patterns that relied on value-type error comparisons From Claude Code Web (ported from my personal fork due to repo access level required). I've read through the code prior to submitting this PR. Prompt: > The scheduled run of .github/workflows/test-go.yaml has had a bunch of errors in integration tests, starting recently. set up and run the tests (including race detection) as if you were running in GotHub Actions, then figure out when the issue was introduced, and what needs to happen to fix the test errors. I expect that smoketests and continued during-dev validation of `main` leading up to 4.83.0 will be sufficient manual testing here. ## Testing - [x] Added/updated automated tests - [ ] QA'd all new/changed functionality manually --------- Co-authored-by: Claude <noreply@anthropic.com>
2026-03-05 15:17:51 +00:00
func (e *AuthHeaderRequiredError) Internal() string {
return e.internal
}
// StatusCode implements kithttp.StatusCoder.
Fix data race in ErrorWithUUID.UUID() causing CI test failures (#40961) Resolves #40857. The scheduled CI runs (with -race enabled) were failing due to a data race in ErrorWithUUID.UUID(). The race occurred between: - HTTP response encoding calling UUID() to lazily initialize the uuid field - Error store background goroutine calling Error() via value-receiver methods, which copies the struct (including the uuid field) concurrently - Logging calls Fix: 1. Use sync.Once for thread-safe lazy UUID initialization 2. Change all value-receiver methods on types embedding ErrorWithUUID to pointer receivers to prevent struct copying that triggers the race 3. Add isNotFoundErr() helper to replace broken errors.Is/errors.As patterns that relied on value-type error comparisons From Claude Code Web (ported from my personal fork due to repo access level required). I've read through the code prior to submitting this PR. Prompt: > The scheduled run of .github/workflows/test-go.yaml has had a bunch of errors in integration tests, starting recently. set up and run the tests (including race detection) as if you were running in GotHub Actions, then figure out when the issue was introduced, and what needs to happen to fix the test errors. I expect that smoketests and continued during-dev validation of `main` leading up to 4.83.0 will be sufficient manual testing here. ## Testing - [x] Added/updated automated tests - [ ] QA'd all new/changed functionality manually --------- Co-authored-by: Claude <noreply@anthropic.com>
2026-03-05 15:17:51 +00:00
func (e *AuthHeaderRequiredError) StatusCode() int {
return http.StatusUnauthorized
}
// IsClientError implements ErrWithIsClientError.
Fix data race in ErrorWithUUID.UUID() causing CI test failures (#40961) Resolves #40857. The scheduled CI runs (with -race enabled) were failing due to a data race in ErrorWithUUID.UUID(). The race occurred between: - HTTP response encoding calling UUID() to lazily initialize the uuid field - Error store background goroutine calling Error() via value-receiver methods, which copies the struct (including the uuid field) concurrently - Logging calls Fix: 1. Use sync.Once for thread-safe lazy UUID initialization 2. Change all value-receiver methods on types embedding ErrorWithUUID to pointer receivers to prevent struct copying that triggers the race 3. Add isNotFoundErr() helper to replace broken errors.Is/errors.As patterns that relied on value-type error comparisons From Claude Code Web (ported from my personal fork due to repo access level required). I've read through the code prior to submitting this PR. Prompt: > The scheduled run of .github/workflows/test-go.yaml has had a bunch of errors in integration tests, starting recently. set up and run the tests (including race detection) as if you were running in GotHub Actions, then figure out when the issue was introduced, and what needs to happen to fix the test errors. I expect that smoketests and continued during-dev validation of `main` leading up to 4.83.0 will be sufficient manual testing here. ## Testing - [x] Added/updated automated tests - [ ] QA'd all new/changed functionality manually --------- Co-authored-by: Claude <noreply@anthropic.com>
2026-03-05 15:17:51 +00:00
func (e *AuthHeaderRequiredError) IsClientError() bool {
return true
}
// ErrPasswordResetRequired is returned when a password reset is required.
var ErrPasswordResetRequired = &passwordResetRequiredError{}
type passwordResetRequiredError struct {
ErrorWithUUID
}
// Error implements the error interface.
Fix data race in ErrorWithUUID.UUID() causing CI test failures (#40961) Resolves #40857. The scheduled CI runs (with -race enabled) were failing due to a data race in ErrorWithUUID.UUID(). The race occurred between: - HTTP response encoding calling UUID() to lazily initialize the uuid field - Error store background goroutine calling Error() via value-receiver methods, which copies the struct (including the uuid field) concurrently - Logging calls Fix: 1. Use sync.Once for thread-safe lazy UUID initialization 2. Change all value-receiver methods on types embedding ErrorWithUUID to pointer receivers to prevent struct copying that triggers the race 3. Add isNotFoundErr() helper to replace broken errors.Is/errors.As patterns that relied on value-type error comparisons From Claude Code Web (ported from my personal fork due to repo access level required). I've read through the code prior to submitting this PR. Prompt: > The scheduled run of .github/workflows/test-go.yaml has had a bunch of errors in integration tests, starting recently. set up and run the tests (including race detection) as if you were running in GotHub Actions, then figure out when the issue was introduced, and what needs to happen to fix the test errors. I expect that smoketests and continued during-dev validation of `main` leading up to 4.83.0 will be sufficient manual testing here. ## Testing - [x] Added/updated automated tests - [ ] QA'd all new/changed functionality manually --------- Co-authored-by: Claude <noreply@anthropic.com>
2026-03-05 15:17:51 +00:00
func (e *passwordResetRequiredError) Error() string {
return "password reset required"
}
// StatusCode implements kithttp.StatusCoder.
Fix data race in ErrorWithUUID.UUID() causing CI test failures (#40961) Resolves #40857. The scheduled CI runs (with -race enabled) were failing due to a data race in ErrorWithUUID.UUID(). The race occurred between: - HTTP response encoding calling UUID() to lazily initialize the uuid field - Error store background goroutine calling Error() via value-receiver methods, which copies the struct (including the uuid field) concurrently - Logging calls Fix: 1. Use sync.Once for thread-safe lazy UUID initialization 2. Change all value-receiver methods on types embedding ErrorWithUUID to pointer receivers to prevent struct copying that triggers the race 3. Add isNotFoundErr() helper to replace broken errors.Is/errors.As patterns that relied on value-type error comparisons From Claude Code Web (ported from my personal fork due to repo access level required). I've read through the code prior to submitting this PR. Prompt: > The scheduled run of .github/workflows/test-go.yaml has had a bunch of errors in integration tests, starting recently. set up and run the tests (including race detection) as if you were running in GotHub Actions, then figure out when the issue was introduced, and what needs to happen to fix the test errors. I expect that smoketests and continued during-dev validation of `main` leading up to 4.83.0 will be sufficient manual testing here. ## Testing - [x] Added/updated automated tests - [ ] QA'd all new/changed functionality manually --------- Co-authored-by: Claude <noreply@anthropic.com>
2026-03-05 15:17:51 +00:00
func (e *passwordResetRequiredError) StatusCode() int {
return http.StatusUnauthorized
}
// IsClientError implements ErrWithIsClientError.
Fix data race in ErrorWithUUID.UUID() causing CI test failures (#40961) Resolves #40857. The scheduled CI runs (with -race enabled) were failing due to a data race in ErrorWithUUID.UUID(). The race occurred between: - HTTP response encoding calling UUID() to lazily initialize the uuid field - Error store background goroutine calling Error() via value-receiver methods, which copies the struct (including the uuid field) concurrently - Logging calls Fix: 1. Use sync.Once for thread-safe lazy UUID initialization 2. Change all value-receiver methods on types embedding ErrorWithUUID to pointer receivers to prevent struct copying that triggers the race 3. Add isNotFoundErr() helper to replace broken errors.Is/errors.As patterns that relied on value-type error comparisons From Claude Code Web (ported from my personal fork due to repo access level required). I've read through the code prior to submitting this PR. Prompt: > The scheduled run of .github/workflows/test-go.yaml has had a bunch of errors in integration tests, starting recently. set up and run the tests (including race detection) as if you were running in GotHub Actions, then figure out when the issue was introduced, and what needs to happen to fix the test errors. I expect that smoketests and continued during-dev validation of `main` leading up to 4.83.0 will be sufficient manual testing here. ## Testing - [x] Added/updated automated tests - [ ] QA'd all new/changed functionality manually --------- Co-authored-by: Claude <noreply@anthropic.com>
2026-03-05 15:17:51 +00:00
func (e *passwordResetRequiredError) IsClientError() bool {
return true
}
// ForbiddenErrorMessage is the error message that should be returned to
// clients when an action is forbidden. It is intentionally vague to prevent
// disclosing information that a client should not have access to.
const ForbiddenErrorMessage = "forbidden"
// CheckMissing is the error to return when no authorization check was performed
// by the service.
type CheckMissing struct {
response any
ErrorWithUUID
}
// CheckMissingWithResponse creates a new error indicating the authorization
// check was missed, and including the response for further analysis by the error
// encoder.
func CheckMissingWithResponse(response any) *CheckMissing {
return &CheckMissing{response: response}
}
// Error implements the error interface.
func (e *CheckMissing) Error() string {
return ForbiddenErrorMessage
}
// Internal implements the ErrWithInternal interface.
func (e *CheckMissing) Internal() string {
return "Missing authorization check"
}
// Response returns the response that was generated before the authorization
// check was found to be missing.
func (e *CheckMissing) Response() any {
return e.response
}