Skip to content

Commit 4787951

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 bb84662 commit 4787951

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
@@ -1329,7 +1329,6 @@ def _get_args(
13291329
k in _NO_NORMALIZE_PARAMS
13301330
or isinstance(v, str)
13311331
or not isinstance(v, Iterable)
1332-
or (isinstance(v, (list, tuple)) and v and not isinstance(v[0], str))
13331332
):
13341333
args[k] = v
13351334
else:

tests/waterdata_test.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -556,3 +556,17 @@ def test_get_daily_parameter_code_as_series(self):
556556
args_dict = fake.call_args[0][0]
557557
assert args_dict["parameter_code"] == ["00060", "00010"]
558558
assert isinstance(args_dict["parameter_code"], list)
559+
560+
def test_list_of_ints_rejected_at_boundary(self):
561+
"""List-of-non-strings must be caught client-side, not silently sent.
562+
563+
Regression: an earlier pass through ``_get_args`` had a
564+
``list-of-non-str`` fast-path that bypassed normalization, so
565+
``parameter_code=[60, 65]`` would reach the OGC API and surface as
566+
a confusing JSONDecodeError on the malformed response.
567+
"""
568+
with pytest.raises(TypeError, match="parameter_code elements must be strings"):
569+
get_daily(
570+
monitoring_location_id="USGS-05427718",
571+
parameter_code=[60, 65],
572+
)

0 commit comments

Comments
 (0)