From 0055e3a52d9360ca1562cf5d7c79803ccd23c0f8 Mon Sep 17 00:00:00 2001 From: Viktor Oreshkin Date: Fri, 11 Sep 2026 20:06:37 +0300 Subject: [PATCH 1/2] fix(api): accept the deprecated headers field in any shape Prowlarr's form POST sends the deprecated headers field as an object, and 1.6.0 refused it because the field is annotated as a list. FlareSolverr v1 declared it as a header map, v2 dropped it, and upstream only warns when it arrives, so no client has a reason to send a list. - Form POSTs from Prowlarr are no longer refused before a solve starts - The field stays unread, so exempting it lets nothing new reach an engine - The class annotation is left as upstream wrote it, so dtos.py still syncs --- src/dtos.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/dtos.py b/src/dtos.py index 3e20d83..8dbc613 100644 --- a/src/dtos.py +++ b/src/dtos.py @@ -77,6 +77,12 @@ def __init__(self, _dict): 'maxTimeout': None, # A fractional wait is meaningful and both engines sleep on it happily. 'waitInSeconds': (int, float), + # Deprecated in FlareSolverr v2 and never read by Solverr; upstream + # FlareSolverr only warns and ignores it. Legacy clients such as Prowlarr + # still send an object here (its HeadersPost), which the `list` annotation + # above would reject outright. Exempt it rather than break a client that + # isn't wrong. + 'headers': None, } _TYPE_NAMES = { From 2226dddd2451dd74d3867e090622380248249c9a Mon Sep 17 00:00:00 2001 From: unseensnick <84652498+unseensnick@users.noreply.github.com> Date: Fri, 11 Sep 2026 19:26:28 +0200 Subject: [PATCH 2/2] test(api): pin that a headers object is accepted Adds the regression test for the headers fix, using the shape Prowlarr's form POST sends, and the CHANGELOG entry for it. The test fails with the exemption removed. --- CHANGELOG.md | 4 ++++ src/test_request_validation.py | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1186d0d..4a4e884 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ Solverr follows its own [Semantic Versioning](https://semver.org/), starting at ## [Unreleased] +### Fixes + +- **Form POST requests from Prowlarr work again, instead of failing with "Request parameter 'headers' must be a list".** 1.6.0 started checking the type of the deprecated `headers` field, which Solverr has never read and which clients send as an object; it is accepted in any shape again and still ignored. + ## [1.6.0] ### Additions diff --git a/src/test_request_validation.py b/src/test_request_validation.py index be4dc7b..b4b1a32 100644 --- a/src/test_request_validation.py +++ b/src/test_request_validation.py @@ -218,6 +218,10 @@ def test_a_boolean_is_not_accepted_as_a_number(self): with self.assertRaises(Exception): self.check(tabs_till_verify=True) + def test_the_deprecated_headers_object_is_accepted(self): + # Prowlarr's form POST sends this shape; the field is never read. + self.assertIsNone(self.check(headers={"contentType": "application/x-www-form-urlencoded"})) + def test_a_numeric_max_timeout_string_is_left_to_its_own_validator(self): # Deliberately coerced rather than type-checked, for callers that work today. self.assertIsNone(self.check(maxTimeout="90000"))