[wp-trac] [WordPress Trac] #64926: REST API: GET requests fail object/array schema validation when params are JSON-serialized strings
WordPress Trac
noreply at wordpress.org
Wed Mar 25 12:31:34 UTC 2026
#64926: REST API: GET requests fail object/array schema validation when params are
JSON-serialized strings
-------------------------------------+-------------------------------------
Reporter: dsmy | Owner: (none)
Type: defect (bug) | Status: new
Priority: normal | Milestone: Awaiting Review
Component: REST API | Version: trunk
Severity: normal | Resolution:
Keywords: needs-patch reporter- | Focuses: javascript, rest-api,
feedback | php-compatibility
-------------------------------------+-------------------------------------
Comment (by dsmy):
Thanks @zieladam!
Even granted that URLSearchParams can construct bracket notation manually,
it's the wrong tool for encoding arbitrary JSON structures. As you've
pointed out, the round-trip is lossy: null vs undefined, boolean false vs
string "false", number 10 vs string "10", arrays vs objects with numeric
keys all collapse in bracket encoding.
decode_from_brackets(encode_as_brackets(data)) !== data.
JSON.stringify() is the only lossless encoding path for structured data in
a query string. That path currently breaks in
rest_validate_value_from_schema().
To give context This came up while working with block attributes through a
custom REST endpoint. We had a read-only endpoint that accepted block
attribute filters as an object param. naturally the thing to do on the JS
side is JSON.stringify() the attributes and pass them as a query param,
especially since that's exactly what works for POST bodies.
Replying to [comment:8 zieladam]:
> URLSearchParams does seem to support that notation:
>
> {{{
> const p = new URLSearchParams();
> p.set('user[name]', 'Bob');
> p.set('user[pet]', 'cat');
> console.log(p+'');
>
> // user%5Bname%5D=Bob&user%5Bpet%5D=cat
> }}}
>
> When I request `/dump.php?user%5Bname%5D=Bob&user%5Bpet%5D=cat` and
`var_dump($_GET)` in there, I get the expected result:
>
> {{{
> array(1) { ["user"]=> array(2) { ["name"]=> string(3) "Bob" ["pet"]=>
string(3) "cat" } }
> }}}
>
> Does that help?
>
> In any case, transforming arbitrary JSON objects into the bracket
notation is lossy. There's to way to distinguish between `null` and
`undefined`, or string `"false"` and boolean `false`, string `"10"` and
number `10`, an array `["hello"]` and an object `{0: "hello"}` etc. It's
just a wrong tool for encoding arbitrary JSON structures as they won't
decode to the initial input. In other words,
`decode_from_brackets(encode_as_brackets(data)) !== data`.
--
Ticket URL: <https://core.trac.wordpress.org/ticket/64926#comment:9>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform
More information about the wp-trac
mailing list