Skip to content

feat: add opt-in retry for RemoteProtocolError and case-insensitive header merging - #40

Merged
Kizy625 merged 3 commits into
mainfrom
fern-bot/2026-10-22_15-36-10_447
Oct 27, 2026
Merged

Kizy625 merged 3 commits into
mainfrom
fern-bot/2026-10-22_15-36-10_447

Conversation

@fern-api

@fern-api fern-api Bot commented Oct 22, 2026

Copy link
Copy Markdown
Contributor

4.0.0 → 4.1.0

Added

  • RequestOptions.retry_remote_protocol_errors — new optional bool field that opts a request into retrying on httpx.RemoteProtocolError (server disconnect / incomplete response); defaults to False and is bounded by max_retries.

Changed

  • RemoteProtocolError retry behavior — the HTTP client no longer retries httpx.RemoteProtocolError automatically; it now raises immediately unless retry_remote_protocol_errors: True is set in RequestOptions, since the server may have already applied the request.
  • Header merging — duplicate headers with different casing (e.g. PLAID-SECRET and plaid-secret) are now deduplicated case-insensitively, with the last value winning; this prevents sending two headers where only one was intended.
  • x-api-key header redaction — the x-api-key header is now redacted alongside Authorization in any debug or log output produced by the HTTP client.
  • Path parameter dot-segment rejection — encode_path_param() and quote_path_param() now raise ValueError when a value is . or .., preventing silent URL path rewriting by HTTP clients.

See full changelog

fern-api Bot added 3 commits October 22, 2026 15:36
Generated by Fern
CLI Version: unknown
Generators:
  - fernapi/fern-python-sdk: 5.41.4
… case-insensitive header merging

Improve HTTP client robustness with two behavioral changes: `RemoteProtocolError`
no longer retries automatically (it now raises immediately unless the caller opts
in via `retry_remote_protocol_errors`), and header merging is now case-insensitive
so duplicate headers with different casing are deduplicated correctly.

Key changes:
- Add `retry_remote_protocol_errors: bool` to `RequestOptions`; `RemoteProtocolError`
  now raises by default instead of retrying, since the server may have already applied
  the request — callers must explicitly opt in to retry this error class
- Add `_merge_headers()` helper that deduplicates headers case-insensitively, preventing
  duplicate headers (e.g. `PLAID-SECRET` + `plaid-secret`) from being sent together
- Add `_AUTH_HEADERS` frozenset (`x-api-key`) so API key headers are redacted alongside
  `Authorization` in debug/log output
- Add `_reject_dot_segment()` guard in `encode_path_param` / `quote_path_param` to reject
  `.` and `..` path parameter values that would silently rewrite the request URL
- Add `_drop_extras_colliding_with_fields()` in `pydantic_utilities` to drop extra keys
  that collide case-insensitively with declared fields, preventing case-insensitive
  decoders (e.g. Go's `encoding/json`) from reading the wrong value

🌿 Generated with Fern
@Kizy625
Kizy625 merged commit 4f32c45 into main Oct 27, 2026
3 checks passed
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.

1 participant