You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Upgrading from qs@6.15.0 to qs@6.15.2 introduced a behavioral change in parse that breaks existing query string handling in Express-based applications using nested bracket group notation.
Context
The 6.15.2 changelog mentions:
[Fix] parse: handle nested bracket groups and add regression tests (#530)
While this is framed as a fix, it changes the parsed output for query strings that were previously handled differently. Applications relying on the prior behavior see regressions without any code change on their end.
are parsed differently between 6.15.0 and 6.15.2, causing API endpoints to receive incorrect or empty parameter values, resulting in empty responses where data is expected.
Suggestion
It would help to:
Clearly document this as a breaking behavioral change in the changelog (not just a fix), so consumers can assess impact before upgrading.
Consider whether the prior behavior was actually incorrect or just undocumented, as many applications may depend on it.
Environment
qs version: 6.15.0 (working) → 6.15.2 (broken)
Used via npm overrides in an Express.js application
The key filters[customtags:Env: Prod is malformed — it has an opening [ but no closing ] (a typo in our code; the : should have been ]=). Even so, the parse output changed between versions:
6.15.0 treats it as a flat key (lenient — unmatched [ ignored):
Yes, our query string is malformed, and fixing it on our side is the right long-term answer. But this is a real behavior change for any app that previously relied on the lenient flat-key fallback for unbalanced brackets. Worth a CHANGELOG callout at minimum.
Closing the loop here: in our case the only failing input was a Newman test typo on our side — filters[customtags:Env: Prod (unclosed [). Diff harness across 10 well-formed shapes from our integration tests + prod traffic vs that 1 malformed case shows only the malformed one differs between 6.15.0 and 6.15.2. So 6.15.2 is safe for us after fixing the typo; the original regression report was a misdiagnosis. Thanks @ljharb for the patient back-and-forth — agreeing 6.15.2's behavior is the right one. Happy for this to be closed (or kept open for your "throw on unbalanced brackets" follow-up, your call).
Activity
darekg11 commentedon May 26, 2026
We are seeing similar behavior after upgrading from
6.15.1to6.15.2I think this fix accidentally slipped a breaking change
ljharb commentedon May 26, 2026
Can you provide a full query string, and the output from both 6.15.1 and 6.15.2?
darekg11 commentedon May 27, 2026
Okay, in our case I think it was the fact that brackets parsing was more relaxed in
6.15.1and what you did is intentional.I guess my comment is irrelevant since it was intended change and we should update our code to not do such constructs of nested arrays when not needed
Israel-Kli commentedon May 31, 2026
We also hit this. Minimal reproduction:
Query string:
groupBy=service&filters[customtags:Env: Prod&startDate=2025-02-01The key
filters[customtags:Env: Prodis malformed — it has an opening[but no closing](a typo in our code; the:should have been]=). Even so, the parse output changed between versions:6.15.0 treats it as a flat key (lenient — unmatched
[ignored):{ "groupBy": "service", "filters[customtags:Env: Prod": "", "startDate": "2025-02-01" }6.15.2 interprets
filters[as starting a nested bracket group despite the missing]:{ "groupBy": "service", "filters": { "[customtags:Env: Prod": "" }, "startDate": "2025-02-01" }Yes, our query string is malformed, and fixing it on our side is the right long-term answer. But this is a real behavior change for any app that previously relied on the lenient flat-key fallback for unbalanced brackets. Worth a CHANGELOG callout at minimum.
ljharb commentedon Jun 2, 2026
@Israel-Kli thanks - tbh i think the thing it should do there is throw.
Israel-Kli commentedon Jun 8, 2026
Closing the loop here: in our case the only failing input was a Newman test typo on our side —
filters[customtags:Env: Prod(unclosed[). Diff harness across 10 well-formed shapes from our integration tests + prod traffic vs that 1 malformed case shows only the malformed one differs between 6.15.0 and 6.15.2. So 6.15.2 is safe for us after fixing the typo; the original regression report was a misdiagnosis. Thanks @ljharb for the patient back-and-forth — agreeing 6.15.2's behavior is the right one. Happy for this to be closed (or kept open for your "throw on unbalanced brackets" follow-up, your call).ljharb commentedon Jun 10, 2026
I'll leave this open until til #560 closes it. Thanks for following up!
[Tests] `parse`: characterize current lenient handling of unbalanced …
[Docs] clarify 6.14.1/6.15.2 parse bracket behavior change