[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
Thu Mar 26 13:57:28 UTC 2026


#64926: REST API: GET requests fail object/array schema validation when params are
JSON-serialized strings
-------------------------+-------------------------------------------------
 Reporter:  dsmy         |       Owner:  (none)
     Type:  defect       |      Status:  new
  (bug)                  |
 Priority:  normal       |   Milestone:  Awaiting Review
Component:  REST API     |     Version:
 Severity:  normal       |  Resolution:
 Keywords:  needs-patch  |     Focuses:  javascript, rest-api, php-
                         |  compatibility
-------------------------+-------------------------------------------------

Comment (by dsmy):

 @zieladam Sure thing!

 This came up while building a structured MCP layer that exposes WordPress
 site capabilities (theme tokens, block settings, animation configs, etc.)
 to an AI agent via declared REST endpoints. Read-only abilities use GET by
 design for the reasons you mentioned around caching and CORS, write
 abilities use POST.

 The problem surfaces when a read-only ability needs structured input. As
 ability schemas get richer, params naturally become objects: filter
 objects, block attribute matchers, config subsets. Declaring those as
 type: object in the endpoint schema is the right call. Passing them from
 the JS client via JSON.stringify() is the natural path, and it breaks on
 GET.

 The block attributes case is where the lossiness you raised was the most
 annoying. Attributes like {"lock":{"move":false,"remove":true}} or
 {"dropCap":false,"className":"hero"} contain booleans and nested objects
 that don't survive bracket encoding intact. Boolean false and string
 "false" are not equivalent when evaluating block state. JSON.stringify()
 is the only lossless encoding path I naturally found that was already
 existing in core, and it already works for POST bodies via
 parse_json_params().

 On your question about whether GET was intended for complex inputs: the
 REST API's own schema system supports type: object and type: array for GET
 params, which suggests the intent was there. The implementation just
 didn't close the loop on the JSON string path side of things.

 The closest historical ticket I was able to find was this one
 https://core.trac.wordpress.org/ticket/42961

 Hope this helps!

 Replying to [comment:11 zieladam]:
 > @dsmy would you be willing to share more information about your use-
 case? While I don't have enough context off-hand to comment on possible
 solutions, I'm thinking that it is weird there is no historical ticket for
 this.
 >
 > I wonder whether the REST API was intended for handling complex inputs
 via GET requests, or was the intention to always use POST. Is it just a
 documentation issue? POST requests are not subject to HTTP caching, for
 example, which wouldn't make sense for  uniquely generated pages
 parametrized by complex JSON structures. POST requests also behave
 differently under CORS etc. etc. Knowing more about your project would be
 a very helpful framing for this discussion.

-- 
Ticket URL: <https://core.trac.wordpress.org/ticket/64926#comment:12>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform


More information about the wp-trac mailing list