FAILURE MAP
← Case archive

FA-191 / Protocols / Open access

Grouping query parameters loses their original order · case 01

Repeated parameters disappear or move past parameters that originally separated them.

Verified by executionVariant 1 · 8 checks per implementationDownload source bundle ↓JSON ↗

ROOT CAUSE

The query string is reduced to a mapping before its ordered, repeated pairs are preserved.

VERIFIED REPAIR

Decode directly into an ordered sequence of key/value pairs and explicitly keep blank values.

Unsuccessful approach: Keeping all values per key preserves multiplicity but loses global interleaving and, by default, empty values.

Case contract

Parse an application/x-www-form-urlencoded query into ordered [key, value] pairs. Preserve repeated keys, empty keys, and empty values; ignore empty separator-only segments.

Why this case matters

Some request-signature, forwarding and audit formats depend on exact ordered parameter multiplicity. A mapping is a lossy intermediate representation for that contract.

1 / The failure

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json
from urllib.parse import parse_qs, parse_qsl
N = 1
observations = []
def solve(query):
    return [[key, values[-1]] for key, values in parse_qs(query, keep_blank_values=True).items()]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('interleaved duplicate keys', solve('a=' + str(N) + '&b=x&a=last'), [['a', str(N)], ['b', 'x'], ['a', 'last']])
check('blank and missing value', solve('a=&b'), [['a', ''], ['b', '']])
check('empty parameter name', solve('=' + str(N)), [['', str(N)]])
check('encoded separators are data', solve('x=a%26b%3Dc'), [['x', 'a&b=c']])
check('plus and encoded plus differ', solve('x=a+b&x=a%2Bb'), [['x', 'a b'], ['x', 'a+b']])
check('repeated identical parameter', solve('&'.join(['k=v'] * (N + 1))), [['k', 'v']] * (N + 1))
check('empty query', solve(''), [])
check('separator-only segments ignored', solve('&&a=1&&'), [['a', '1']])
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
interleaved duplicate keys[['a', 'last'], ['b', 'x']][['a', '1'], ['b', 'x'], ['a', 'last']]Failed
blank and missing value[['a', ''], ['b', '']][['a', ''], ['b', '']]Passed
empty parameter name[['', '1']][['', '1']]Passed
encoded separators are data[['x', 'a&b=c']][['x', 'a&b=c']]Passed
plus and encoded plus differ[['x', 'a+b']][['x', 'a b'], ['x', 'a+b']]Failed
repeated identical parameter[['k', 'v']][['k', 'v'], ['k', 'v']]Failed
empty query[][]Passed
separator-only segments ignored[['a', '1']][['a', '1']]Passed

SHA-256 / 28bebdac34860a5eb1ef1c6ee5c5d5a8b2dbff25ef52ca80d6d83821447b5aaf

2 / The unsuccessful fix

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json
from urllib.parse import parse_qs, parse_qsl
N = 1
observations = []
def solve(query):
    return [[key, value] for key, values in parse_qs(query).items() for value in values]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('interleaved duplicate keys', solve('a=' + str(N) + '&b=x&a=last'), [['a', str(N)], ['b', 'x'], ['a', 'last']])
check('blank and missing value', solve('a=&b'), [['a', ''], ['b', '']])
check('empty parameter name', solve('=' + str(N)), [['', str(N)]])
check('encoded separators are data', solve('x=a%26b%3Dc'), [['x', 'a&b=c']])
check('plus and encoded plus differ', solve('x=a+b&x=a%2Bb'), [['x', 'a b'], ['x', 'a+b']])
check('repeated identical parameter', solve('&'.join(['k=v'] * (N + 1))), [['k', 'v']] * (N + 1))
check('empty query', solve(''), [])
check('separator-only segments ignored', solve('&&a=1&&'), [['a', '1']])
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
interleaved duplicate keys[['a', '1'], ['a', 'last'], ['b', 'x']][['a', '1'], ['b', 'x'], ['a', 'last']]Failed
blank and missing value[][['a', ''], ['b', '']]Failed
empty parameter name[['', '1']][['', '1']]Passed
encoded separators are data[['x', 'a&b=c']][['x', 'a&b=c']]Passed
plus and encoded plus differ[['x', 'a b'], ['x', 'a+b']][['x', 'a b'], ['x', 'a+b']]Passed
repeated identical parameter[['k', 'v'], ['k', 'v']][['k', 'v'], ['k', 'v']]Passed
empty query[][]Passed
separator-only segments ignored[['a', '1']][['a', '1']]Passed

SHA-256 / 50adf09e5c92290de7c635d3c009cdbb17aa0eef50bb00a4367451a196153090

3 / The verified repair

Exit 0
"""Failure Map reference implementation. Python standard library only."""
import json
from urllib.parse import parse_qs, parse_qsl
N = 1
observations = []
def solve(query):
    return [list(pair) for pair in parse_qsl(query, keep_blank_values=True)]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('interleaved duplicate keys', solve('a=' + str(N) + '&b=x&a=last'), [['a', str(N)], ['b', 'x'], ['a', 'last']])
check('blank and missing value', solve('a=&b'), [['a', ''], ['b', '']])
check('empty parameter name', solve('=' + str(N)), [['', str(N)]])
check('encoded separators are data', solve('x=a%26b%3Dc'), [['x', 'a&b=c']])
check('plus and encoded plus differ', solve('x=a+b&x=a%2Bb'), [['x', 'a b'], ['x', 'a+b']])
check('repeated identical parameter', solve('&'.join(['k=v'] * (N + 1))), [['k', 'v']] * (N + 1))
check('empty query', solve(''), [])
check('separator-only segments ignored', solve('&&a=1&&'), [['a', '1']])
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
interleaved duplicate keys[['a', '1'], ['b', 'x'], ['a', 'last']][['a', '1'], ['b', 'x'], ['a', 'last']]Passed
blank and missing value[['a', ''], ['b', '']][['a', ''], ['b', '']]Passed
empty parameter name[['', '1']][['', '1']]Passed
encoded separators are data[['x', 'a&b=c']][['x', 'a&b=c']]Passed
plus and encoded plus differ[['x', 'a b'], ['x', 'a+b']][['x', 'a b'], ['x', 'a+b']]Passed
repeated identical parameter[['k', 'v'], ['k', 'v']][['k', 'v'], ['k', 'v']]Passed
empty query[][]Passed
separator-only segments ignored[['a', '1']][['a', '1']]Passed

SHA-256 / e1a99e7c74dc816452c55d2343d3119d137efacc4c65451d9407b5c2838ede57

Verification & scope

This reproducer isolates one failure mechanism. Results cover the supplied fixtures. Variants within a family share a test contract and should remain grouped when constructing evaluation splits. Related mechanisms with a shared evaluation_group must also remain together; these controlled models are not independent production incidents.

Observations recorded using Python 3.12.14 at 2026-09-29T14:36:51.018756+00:00.

Case digest / ec69e06208cac1007d81ddff636f896ae03bb3aba90fd60d3cd8d176d7428ee0