Skip to content

Commit 8dc70b2

Browse files
committed
Reject list-of-non-strings at boundary instead of silently passing through
Live stress test found that `parameter_code=[60, 65]` (ints) was silently passed to the OGC API, surfacing as a confusing JSONDecodeError when the server returned an error page. The "list-of-non-str pass-through" clause in `_get_args` was a defensive shortcut intended for `bbox`/`boundingBox` (which are `list[float]`), but those params are already covered by `_NO_NORMALIZE_PARAMS`, making the clause redundant AND bug-silencing. Now `_normalize_str_iterable` runs for every non-listed list-shaped param, raising TypeError with the offending element type — same path that already handles `monitoring_location_id=[..., 12345]`.
1 parent 07ed123 commit 8dc70b2

2 files changed

Lines changed: 14 additions & 1 deletion

File tree

dataretrieval/waterdata/utils.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1345,7 +1345,6 @@ def _get_args(
13451345
k in _NO_NORMALIZE_PARAMS
13461346
or isinstance(v, str)
13471347
or not isinstance(v, Iterable)
1348-
or (isinstance(v, (list, tuple)) and v and not isinstance(v[0], str))
13491348
):
13501349
args[k] = v
13511350
else:

tests/waterdata_test.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -680,3 +680,17 @@ def test_get_daily_parameter_code_as_series(self):
680680
args_dict = fake.call_args[0][0]
681681
assert args_dict["parameter_code"] == ["00060", "00010"]
682682
assert isinstance(args_dict["parameter_code"], list)
683+
684+
def test_list_of_ints_rejected_at_boundary(self):
685+
"""List-of-non-strings must be caught client-side, not silently sent.
686+
687+
Regression: an earlier pass through ``_get_args`` had a
688+
``list-of-non-str`` fast-path that bypassed normalization, so
689+
``parameter_code=[60, 65]`` would reach the OGC API and surface as
690+
a confusing JSONDecodeError on the malformed response.
691+
"""
692+
with pytest.raises(TypeError, match="parameter_code elements must be strings"):
693+
get_daily(
694+
monitoring_location_id="USGS-05427718",
695+
parameter_code=[60, 65],
696+
)

0 commit comments

Comments
 (0)