Skip to content

fix(finch): unwrap error structs introduced by finch 0.22 - #902

Merged
yordis merged 3 commits into
masterfrom
dependabot/hex/prod-2b9557ea58
Aug 6, 2026
Merged

fix(finch): unwrap error structs introduced by finch 0.22#902
yordis merged 3 commits into
masterfrom
dependabot/hex/prod-2b9557ea58

Conversation

@dependabot

@dependabot dependabot Bot commented on behalf of github Aug 1, 2026

Copy link
Copy Markdown
Contributor
  • Finch v0.22 standardized every failure behind Finch.error(), so the adapter
    started leaking wrapper structs instead of the bare reasons callers have always
    matched on. Upgrading Finch without this is a silent breaking change for anyone
    matching {:error, :timeout}.
  • Mint's connection structs are opaque, so Dialyzer cannot verify the close/1
    delegation against HTTP.t(). The accurate spec is kept and the check is scoped
    off rather than relaxed to term().

Bumps the prod group with 6 updates in the / directory:

Package From To
castore 1.0.14 1.0.20
finch 0.19.0 0.23.0
gun 2.2.0 2.5.0
hackney 4.1.0 4.6.0
ibrowse 4.4.2 4.5.0
jason 1.4.4 1.4.5

Updates castore from 1.0.14 to 1.0.20

Commits

Updates finch from 0.19.0 to 0.23.0

Changelog

Sourced from finch's changelog.

v0.23.0 (2026-06-17)

Fixed

  • Reject http and https request and pool URLs without hosts before attempting requests #371, fixes #186
  • Drop :certs_keys, :certfile, and :keyfile from TCP transport options for HTTP requests to avoid :badarg errors #377
  • Fix a race condition when dynamically starting pool supervisors that could return :pool_not_available while workers were still registering #379
  • Make the HTTP/2 ALPN negotiation failure assertion compatible with OTP 29 TLS alert capitalization #378

Other

  • Update development and test dependencies, including Mint 1.9 #378
  • CI: update to Elixir 1.20.1 and Erlang/OTP 29.0.2 and fix Credo issues #378

v0.22.0 (2026-05-12)

Added

  • Add a new :http2 configuration section with :wait_for_server_settings?, :ping_interval, :max_connection_age, and :max_connection_age_jitter support #354 #355 #364
  • Add http+unix:// and https+unix:// URL scheme support for cleaner Unix socket pool configuration #351
  • Add pool tagging support for connection pool isolation #342
  • Add dynamic and user-managed pool APIs with Finch.start_pool/3, Finch.find_pool/2, and Finch.Pool.child_spec/1 #352
  • Add Finch.is_request_ref/1 for matching async request refs in guards #350
  • Add configurable pool worker selection strategies via :pool_strategy #359
  • Add runtime pool resizing with Finch.get_pool_count/2 and Finch.set_pool_count/3 #362
  • Add pid, max_concurrent_streams, and available_connections to pool metrics #362 #368
  • Support {:stream, req_body_fun} request bodies in Finch.stream_while/5 on HTTP/1 #357 #360
  • Encapsulate pool identity using a Finch.Pool struct #338
  • Add Elixir 1.20 support #346

Changed

  • Require Elixir v1.15 #358
  • Refactor pool management to use per-pool supervisors and registry-backed tracking #344
  • Pool metrics now return Finch.Pool.t() structs as keys and use ordered-set ETS tables for prefix lookups #342 #368
  • Register only ready HTTP/2 connections, returning :pool_not_available when no connected pool is available #356
  • Standardize error handling with Finch.error(), Finch.HTTPError, and Finch.TransportError #341
  • Validate keyword options in Finch.build/5 and Finch.request/3 #365
  • Use Mint 1.8 #341

Deprecated

  • Deprecate {scheme, {:local, path}} tuple form in :pools, use URL strings (e.g. "http+unix:///path") instead #351

Removed

  • Remove deprecated Finch.request/6 function, pool configuration options, and :max_idle_time_exceeded telemetry event #348

Fixed

... (truncated)

Commits
  • 5841aa5 prepare release 0.23.0
  • 0bd54bb mix format
  • 9a514a7 refactor: extract Finch.URI.fetch_host!/1
  • 1abf5a9 validate URL hosts before requests
  • 5a454b7 Fix race condition when dynamically starting pool supervisors
  • aba10e0 Bump CI to Elixir 1.20.1/OTP 29.0.2 and fix all credo issues
  • a028a5e Update deps to latest and fix OTP 29 TLS test
  • 9a6bdd1 Add certs_keys, certfile, keyfile to dropped TLS options
  • 41def29 fix warning during mix docs
  • 3191809 Merge pull request #372 from sneako/codex/prepare-0.22.0
  • Additional commits viewable in compare view

Updates gun from 2.2.0 to 2.5.0

Commits
  • 59e11ae Fix CTL cookie tests following stricter parsing
  • 5e0c66c Gun 2.5.0
  • 2418095 Add HTTP/2 max_headers option to types and documentation
  • c269fcb Reactivate socket when a response ends
  • 40e7ec1 Update Erlang.mk
  • e7af4a9 Add compat Websocket compression option
  • 5a2f77e Don't send server_max_window_bits=15, it's the default
  • 4b8ed81 Gun 2.4.1
  • 8cc70ed Gun 2.4.0
  • c00ca7a Update Cowlib to 2.17.0
  • Additional commits viewable in compare view

Updates hackney from 4.1.0 to 4.6.0

Release notes

Sourced from hackney's releases.

4.6.0

Added

  • set_owner/2 now works while a response body is streaming, in both the synchronous and the async path. It used to return {error, invalid_state} once the body had started. This lets a short lived worker run a request and hand the still streaming response to a longer lived process before it exits, without stopping the connection.
  • connect/4 accepts a binary host, restoring the 1.x behavior. A binary is converted to a string, so callers passing a binary host no longer fail.

Fixed

  • A non-reusable connection (flagged no_reuse for proxy tunnels, SSL upgrades or a disabled pool, or answered with Connection: close) is now closed and its process stopped when a synchronous request completes, instead of parking in connected forever. With a long lived owner nothing stopped it, so one hackney_conn process leaked per request until the node ran out of memory (#902). The sync and async reuse decision now share the same check, which also stops a no_reuse pooled connection on the async path.

hackney 4.5.2

Dependency bump release. No API changes.

Changed

  • Bump h2 to 0.10.4. It fixes a regression from 0.10.3 where a blocking send whose data had fully drained received {error, stream_closed} when the stream closed on its END_STREAM chunk. A waiting sender is now settled as ok once the send buffer has drained, and only gets the close-reason error when data is still outstanding.
  • Bump quic to 1.7.0. Relevant to hackney's HTTP/3 client: the connection flow-control window now slides forward with received bytes instead of stalling after 8 MiB, so large HTTP/3 downloads keep flowing; the idle timer restarts on received activity per RFC 9000 §10.1; an invalid peer SETTINGS frame now closes the connection cleanly instead of crashing; and a client recognizes a server stateless reset (RFC 9000 §10.3) and closes promptly instead of waiting for the idle timeout.
  • Bump webtransport to 0.4.3, which aligns its transitive h2 (0.10.4) and quic (1.7.0) dependencies with hackney's own, so the wt_* API runs on the same HTTP/2 and HTTP/3 stack versions.

4.5.1

Changed

  • Bump h2 to 0.10.3. It fixes an HTTP/2 upload hang: a sender blocked on flow control is now released with {error, stream_reset} or {error, stream_closed} when the peer cancels the stream, instead of hanging for the connection's lifetime. This affects hackney's streamed request bodies over HTTP/2 when the server resets the stream mid-backpressure.

4.5.0

Added

  • HTTP QUERY method (RFC 10008) as a first-class method: hackney:query/1..4 helpers and hackney:request(query, ...). QUERY is safe and idempotent and carries a request body like POST. It works over HTTP/1.1, HTTP/2, and HTTP/3 with every request body mode (binary, streamed, async, connection API).

4.4.5

Fixed

  • HTTPS: a connection reused over a resumed TLS 1.3 session is no longer mislabeled as HTTP/1 when it negotiated HTTP/2. ssl:negotiated_protocol/1 reports nothing on a resumed session, so hackney now remembers the protocol learned on the full handshake (per host and advertised ALPN) and offers resumption only once that protocol is known, resolving a resumed session against that snapshot. Reused h2 connections take the h2 path instead of feeding h2 frames to the HTTP/1 parser.
  • HTTP/1.1: a response that cannot begin an HTTP/1 status line (for example an

... (truncated)

Changelog

Sourced from hackney's changelog.

4.6.0 - 2026-07-15

Added

  • set_owner/2 now works while a response body is streaming, in both the synchronous and the async path. It used to return {error, invalid_state} once the body had started. This lets a short lived worker run a request and hand the still streaming response to a longer lived process before it exits, without stopping the connection.
  • connect/4 accepts a binary host, restoring the 1.x behavior. A binary is converted to a string, so callers passing a binary host no longer fail.

Fixed

  • A non-reusable connection (flagged no_reuse for proxy tunnels, SSL upgrades or a disabled pool, or answered with Connection: close) is now closed and its process stopped when a synchronous request completes, instead of parking in connected forever. With a long lived owner nothing stopped it, so one hackney_conn process leaked per request until the node ran out of memory (#902). The sync and async reuse decision now share the same check, which also stops a no_reuse pooled connection on the async path.

4.5.2 - 2026-07-06

Changed

  • Bump h2 to 0.10.4. It fixes a regression from 0.10.3 where a blocking send whose data had fully drained received {error, stream_closed} when the stream closed on its END_STREAM chunk. A waiting sender is now settled as ok once the send buffer has drained, and only gets the close-reason error when data is still outstanding.
  • Bump quic to 1.7.0. Relevant to hackney's HTTP/3 client: the connection flow-control window now slides forward with received bytes instead of stalling after 8 MiB, so large HTTP/3 downloads keep flowing; the idle timer restarts on received activity per RFC 9000 §10.1; an invalid peer SETTINGS frame now closes the connection cleanly instead of crashing; and a client recognizes a server stateless reset (RFC 9000 §10.3) and closes promptly instead of waiting for the idle timeout.
  • Bump webtransport to 0.4.3, which aligns its transitive h2 (0.10.4) and quic (1.7.0) dependencies with hackney's own, so the wt_* API runs on the same HTTP/2 and HTTP/3 stack versions.

4.5.1 - 2026-07-04

Changed

  • Bump h2 to 0.10.3. It fixes an HTTP/2 upload hang: a sender blocked on

... (truncated)

Commits
  • 42058d1 Release 4.6.0
  • 2f6d15b Merge pull request #908 from benoitc/proto/unified-finish-request
  • 750869c Stop non-reusable connections when a request completes
  • 398edbd Merge pull request #906 from TBK145/patch-1
  • 08a0393 Merge connect/4 clauses under one spec so it compiles
  • 6430334 Merge pull request #904 from benoitc/feature/set-owner-mid-stream
  • 24bbf44 Overload connect function to accept binary host
  • 89eb0f6 Add regression test for set_owner API in unchanged states
  • a0c5e5e Allow set_owner while a response body is streaming
  • d5051db Release 4.5.2: bump h2 0.10.4, quic 1.7.0, webtransport 0.4.3
  • Additional commits viewable in compare view

Updates ibrowse from 4.4.2 to 4.5.0

Release notes

Sourced from ibrowse's releases.

v4.5.0

What's Changed

New Contributors

Full Changelog: cmullaparthi/ibrowse@v4.4.2...v4.5.0

Changelog

Sourced from ibrowse's changelog.

CONTRIBUTIONS & CHANGE HISTORY

01-05-2026 - v4.5.0 * Added connect_to request option for connecting to an alternate network target while preserving the original URL host for the Host header, cookies, and TLS SNI (PR#183) * Added format_status/1 callback to strip sensitive data from gen_server status output (PR#182) * Bumped minimum supported Erlang/OTP version to 25; replaced Travis CI with GitHub Actions (PR#181) * Added option to disable trap_exit in worker processes so external connection pools can rely on link-based cleanup (PR#171) * Internal timestamps are now strictly monotonic, and the pre-OTP-25 fallback path has been removed (PR#173, PR#185) * Performance: refactored chunk_request_body so the Erlang compiler can reuse the binary match context; added chunk-encoding tests to CI (PR#184) * Performance: replaced lists:keysearch/3 with the more efficient lists:keyfind/3 (PR#186) * Added a helper to update download_dir in the internal config ETS table at runtime (PR#158) * Fix: routing acquires a fresh load-balancer pid if the cached one is no longer alive (PR#166) * Test/build: use ssl:handshake/2 on OTP 21+, increased timeout in the small_pipeline test, miscellaneous typo fixes (PR#172, PR#174, PR#175)

21-09-2018 - v4.4.2 * Fix for #163 - default to using IPv4

23-08-2018 - v4.4.1 * Fixes to TLS socket handling (PR#163) * Fix ipv6 address family handling (PR#155) * Don't send messages to closed/inactive connections (PR#152)

28-01-2017 - v4.4 * Fixes to SOCKS over SSL processing * Added stream_full_chunks option * Merged pull requests 145, 151

07-06-2016 - v4.3 * Adopted erlang.mk for compiling. I find it easier to understand how 'make' behaves compared to rebar. This repo can still be built using rebar for those who prefer it * Removed references to lager. Introduced configurable logging function * Fixed an issue where the calling process was getting an extra spurious timeout message when the request was timing out

... (truncated)

Commits

Updates jason from 1.4.4 to 1.4.5

Changelog

Sourced from jason's changelog.

1.4.5 (05.05.2026)

  • Add support for Decimal 3.0
Commits
  • 4ede428 Bump v1.4.5
  • b8c2185 Fix dialyzer job
  • a363975 Modernise CI to currently supported versions
  • 243c8a8 Allow decimal 3.0
  • c8e8d05 Revert the experimental 1.5 branch and jason_native experiment
  • 0e7a3e2 Add example/doctest for Jason.OrderedObject.new/1
  • 984bc07 fix broken link
  • f775592 Raise if trying to decode decimals without decimal
  • 79d59df Remove unneeded workarounds for xref warnings
  • baac78e Fix warnings by conditionally compiling Decimal support
  • Additional commits viewable in compare view

Updates mint from 1.7.1 to 1.9.3

Changelog

Sourced from mint's changelog.

v1.9.3

  • Prevent signed integers when parsing HTTP/1 chunk sizes. This is a fix for CVE-2026-59249 (GitHub advisory).

v1.9.2

  • Cap HTTP/1 total header size for responses. This is a fix for CVE-2026-58229 (GitHub advisory GHSA-qrfr-wh4c-3qhw).
  • Do not store empty CONTINUATION (HTTP/2) frames. This is a fix for CVE-2026-59246 (GitHub advisory GHSA-8pf6-g464-h6h9).

v1.9.1

Security

  • HTTP/1.1 chunked response bodies are now emitted as {:data, ref, data} tuples as soon as data from the chunked body is received. This prevents CVE-2026-56810: the previous behavior was to buffer body chunks according to their advertised length. An attacker could craft a chunked response with a very large chunk length, and Mint would keep accumulating incoming chunked bytes in memory until reaching that length—allowing the attacker to OOM the application using Mint. See also the GHSA-c59h-fq4p-r36r GitHub advisory.

v1.9.0

Security

  • Validate the HTTP/1.1 request method as an RFC 9110 token, rejecting CRLF and other control characters. Forwarding attacker-controlled input as the request method was exposed to CRLF injection (request header injection and request smuggling). Fixes GHSA-2pg6-44cx-c49v.
  • Reject HTTP/1.1 content-length header values that are not strictly 1*DIGIT, so signed values (such as +0) and embedded whitespace no longer parse as valid lengths. This parser disagreement with a strict fronting proxy was a response-smuggling primitive. Fixes GHSA-mjqx-c6f6-7rc2.
  • Bound the HTTP/2 accumulated header block by the locally advertised SETTINGS_MAX_HEADER_LIST_SIZE (now defaulting to 256 KB instead of :infinity), so a malicious server can no longer exhaust client memory with an unbounded chain of CONTINUATION frames. Fixes GHSA-2p26-p43x-fhp8.
  • Count reserved HTTP/2 streams against max_concurrent_streams at PUSH_PROMISE time and refuse promises past the limit with RST_STREAM, so a malicious server can no longer exhaust client memory by flooding PUSH_PROMISE frames. Fixes GHSA-g586-ccqf-7x4r.

Bug Fixes and Improvements

  • Mint.HTTP.stream/2 now returns :unknown (not :unknown_message) when given a message it does not recognize.

v1.8.0

New features

  • Raise the default HTTP/2 receive windows to 16 MB (connection) and 4 MB (stream), and batch HTTP/2 receive-window refills. The larger windows lift the per-stream throughput cap (window / RTT), giving substantially higher throughput on higher-latency connections, in exchange for higher peak memory use per connection. The connection-level window is now configurable via the new :connection_window_size option to Mint.HTTP.connect/4, and refill batching is configurable via the new :receive_window_update_threshold option.
  • Add Mint.HTTP2.set_window_size/3 for advertising a larger receive window to the server after a connection has been established.
  • Add Mint.HTTP.request_body_window/2 for querying the available send-window when streaming a request body.
  • Introduce the :optional_responses option for Mint.HTTP1.connect/4, with a :status_reason value that surfaces the HTTP/1.1 status reason-phrase as a new {:status_reason, request_ref, reason_phrase} response.
  • Change t:Mint.HTTP.t/0 from an opaque to an open type.
  • Add t:Mint.HTTPError.reason/0 and t:Mint.TransportError.reason/0.

Bug Fixes and Improvements

  • Fix HTTP/1 handling of 1xx informational responses.
  • Forbid or replace empty targets in HTTP/1.1 requests.
Commits

@dependabot dependabot Bot added dependencies Pull requests that update a dependency file elixir Pull requests that update Elixir code labels Aug 1, 2026
@cursor

cursor Bot commented Aug 1, 2026

Copy link
Copy Markdown

PR Summary

Medium Risk
Touches core HTTP adapters and pulls in Mint security fixes, but the main behavioral risk is dependency/API drift; the Finch unwrap is an intentional compatibility shim for error matching.

Overview
Bumps optional production HTTP stack dependencies (notably Finch 0.19→0.23, Mint 1.7→1.9.3, hackney 4.1→4.6, plus ibrowse, castore, jason, and transitive lockfile updates) and pins ibrowse to 4.5.0 in mix.exs.

Finch 0.22+ wraps failures in Finch.TransportError / Finch.HTTPError; the Finch adapter now routes all {:error, reason} results through unwrap_error/1 so Tesla still returns the same bare reasons (e.g. Mint transport atoms) that callers matched on before.

The Mint adapter adds a @dialyzer {:nowarn_function, close: 1} on close/1 after Mint’s type changes made the HTTP.close/1 delegation unverifiable.

Reviewed by Cursor Bugbot for commit b68a979. Bugbot is set up for automated code reviews on this repo. Configure here.

Comment thread mix.lock
Bumps the prod group with 6 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [castore](https://github.com/elixir-mint/castore) | `1.0.14` | `1.0.20` |
| [finch](https://github.com/sneako/finch) | `0.19.0` | `0.23.0` |
| [gun](https://github.com/ninenines/gun) | `2.2.0` | `2.5.0` |
| [hackney](https://github.com/benoitc/hackney) | `4.1.0` | `4.6.0` |
| [ibrowse](https://github.com/cmullaparthi/ibrowse) | `4.4.2` | `4.5.0` |
| [jason](https://github.com/michalmuskala/jason) | `1.4.4` | `1.4.5` |



Updates `castore` from 1.0.14 to 1.0.20
- [Commits](elixir-mint/castore@v1.0.14...v1.0.20)

Updates `finch` from 0.19.0 to 0.23.0
- [Changelog](https://github.com/sneako/finch/blob/main/CHANGELOG.md)
- [Commits](sneako/finch@v0.19.0...v0.23.0)

Updates `gun` from 2.2.0 to 2.5.0
- [Commits](ninenines/gun@2.2.0...2.5.0)

Updates `hackney` from 4.1.0 to 4.6.0
- [Release notes](https://github.com/benoitc/hackney/releases)
- [Changelog](https://github.com/benoitc/hackney/blob/master/NEWS.md)
- [Commits](benoitc/hackney@4.1.0...4.6.0)

Updates `ibrowse` from 4.4.2 to 4.5.0
- [Release notes](https://github.com/cmullaparthi/ibrowse/releases)
- [Changelog](https://github.com/cmullaparthi/ibrowse/blob/master/CHANGELOG)
- [Commits](cmullaparthi/ibrowse@v4.4.2...v4.5.0)

Updates `jason` from 1.4.4 to 1.4.5
- [Release notes](https://github.com/michalmuskala/jason/releases)
- [Changelog](https://github.com/michalmuskala/jason/blob/master/CHANGELOG.md)
- [Commits](michalmuskala/jason@v1.4.4...v1.4.5)

Updates `mint` from 1.7.1 to 1.9.3
- [Changelog](https://github.com/elixir-mint/mint/blob/main/CHANGELOG.md)
- [Commits](elixir-mint/mint@v1.7.1...v1.9.3)

---
updated-dependencies:
- dependency-name: castore
  dependency-version: 1.0.20
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: prod
- dependency-name: finch
  dependency-version: 0.23.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod
- dependency-name: gun
  dependency-version: 2.5.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod
- dependency-name: hackney
  dependency-version: 4.6.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod
- dependency-name: ibrowse
  dependency-version: 4.5.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod
- dependency-name: jason
  dependency-version: 1.4.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: prod
- dependency-name: mint
  dependency-version: 1.9.3
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod
...

Signed-off-by: dependabot[bot] <support@github.com>
@dependabot dependabot Bot changed the title chore(deps): bump the prod group with 7 updates chore(deps): bump the prod group across 1 directory with 7 updates Aug 1, 2026
@dependabot
dependabot Bot force-pushed the dependabot/hex/prod-2b9557ea58 branch from e9ef79f to c4f3a85 Compare August 1, 2026 18:18
yordis added 2 commits August 6, 2026 17:43
Finch v0.22 standardized every failure behind `Finch.error()`, which silently
changed the error terms Tesla returned to callers.

Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>
Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>
@yordis yordis changed the title chore(deps): bump the prod group across 1 directory with 7 updates fix(finch): unwrap error structs introduced by finch 0.22 Aug 6, 2026

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit b68a979. Configure here.

Comment thread lib/tesla/adapter/finch.ex
@yordis
yordis merged commit a833717 into master Aug 6, 2026
1 check passed
@yordis
yordis deleted the dependabot/hex/prod-2b9557ea58 branch August 6, 2026 22:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Pull requests that update a dependency file elixir Pull requests that update Elixir code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant