Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
### Fixed

- Log a DEBUG message rather than error when we can't find a Xcode archive for React Native iOS. [#276](https://github.com/bugsnag/bugsnag-cli/pull/276)
- Fixed retry failures caused by request body not being reset between retry attempts. [#277](https://github.com/bugsnag/bugsnag-cli/pull/277)

## [3.9.0] - 2026-03-11

Expand Down
26 changes: 24 additions & 2 deletions pkg/server/request.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,11 +95,19 @@ func buildFileRequest(url string, fieldData map[string]string, fileFieldData map

writer.Close()

request, err := http.NewRequest("POST", url, body)
// Store the body bytes so we can recreate the body for retries
bodyBytes := body.Bytes()

request, err := http.NewRequest("POST", url, bytes.NewReader(bodyBytes))
if err != nil {
return nil, err
}

// Set GetBody to allow the request body to be re-read on retry attempts
request.GetBody = func() (io.ReadCloser, error) {
return io.NopCloser(bytes.NewReader(bodyBytes)), nil
}

request.Header.Add("Content-Type", writer.FormDataContentType())

return request, nil
Expand Down Expand Up @@ -190,9 +198,14 @@ func ProcessBuildRequest(apiKey string, payload []byte, options options.CLI, log
return fmt.Errorf("error getting upload endpoint: %w", err)
}

req, _ := http.NewRequest("POST", endpoint, bytes.NewBuffer(payload))
req, _ := http.NewRequest("POST", endpoint, bytes.NewReader(payload))
req.Header.Add("Content-Type", "application/json")

// Set GetBody to allow the request body to be re-read on retry attempts
req.GetBody = func() (io.ReadCloser, error) {
return io.NopCloser(bytes.NewReader(payload)), nil
}

if !options.DryRun {
logger.Info(fmt.Sprintf("Sending build information to %s", endpoint))

Expand Down Expand Up @@ -238,6 +251,15 @@ func processRequest(request *http.Request, timeout int, retryCount int, logger l

logger.Warn("Request Failed, Retrying...")

// Reset the request body for retry using GetBody if available
if request.GetBody != nil {
body, bodyErr := request.GetBody()
if bodyErr != nil {
return errors.Wrap(bodyErr, "failed to reset request body for retry")
}
request.Body = body
}

time.Sleep(time.Second)
}

Expand Down
Loading