Skip to content

fix: re-encode multipart body on request retry - #819

Open
RaphaelFakhri wants to merge 1 commit into
auth0:masterfrom
RaphaelFakhri:fix/multipart-retry-encoder
Open

RaphaelFakhri wants to merge 1 commit into
auth0:masterfrom
RaphaelFakhri:fix/multipart-retry-encoder

Conversation

@RaphaelFakhri

Copy link
Copy Markdown

Changes

When a multipart request gets a retryable status (408, 429 or 5xx), Internal::Http::RawClient#send calls request.encode_body again for the retry. Internal::Multipart::FormData keeps one Encoder, and Encoder#encode closes it after the first call, so the retry raises RuntimeError: Cannot write to closed encoder and is never sent. This affects jobs.users_imports.create.

This change makes Encoder#encode start from an empty body on each call. The boundary stays the same, so the Content-Type header built from it still matches the body on every attempt.

  • Methods changed: Auth0::Internal::Multipart::Encoder#encode (internal, @api private). No public API changes.
  • After retries run out, a 429 on a users import now raises Auth0::Errors::ClientError, the same as JSON requests, instead of a RuntimeError.

References

Testing

test/unit/internal/multipart/test_multipart_encoder.rb adds two tests:

  • Encoding the same FormData twice returns the same payload, with one closing boundary.
  • A Multipart::Request sent through RawClient that gets a 503 and then a 201 sends the same body on both attempts.

Both tests fail on master with RuntimeError: Cannot write to closed encoder and pass with this change. bundle exec rake test passes on Ruby 3.3 (609 runs, 0 failures). The reproduction script from #818 now raises Auth0::Errors::ClientError instead of RuntimeError.

  • This change adds unit test coverage
  • This change adds integration test coverage
  • This change has been tested on the latest version of Ruby

Checklist

@RaphaelFakhri
RaphaelFakhri requested a review from a team as a code owner October 24, 2026 16:48

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Retrying a multipart request raises "Cannot write to closed encoder"

1 participant