[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