[wp-trac] [WordPress Trac] #64467: Media Library Grid view displays attachments in the wrong order when an order query var is present but not normalized (e.g. `order=desc` or `order=pizza`). Not a `WP_Query` / database issue: the server returns correctly ordered results; the UI reverses them client‑side in JavaScript.

WordPress Trac noreply at wordpress.org
Thu Jan 1 08:05:50 UTC 2026


#64467: Media Library Grid view displays attachments in the wrong order when an
order query var is present but not normalized (e.g. `order=desc` or
`order=pizza`). Not a `WP_Query` / database issue: the server returns
correctly ordered results; the UI reverses them client‑side in JavaScript.
-------------------------+-------------------------------------------------
 Reporter:               |      Owner:  (none)
  trivedikavit           |
     Type:  defect       |     Status:  new
  (bug)                  |
 Priority:  normal       |  Milestone:  Awaiting Review
Component:  Media        |    Version:
 Severity:  minor        |   Keywords:  has-patch needs-testing has-test-
  Focuses:  javascript   |  info has-screenshots javascript
-------------------------+-------------------------------------------------
 = Are you using either the latest version of WordPress, or the latest
 development version? =

 Yes. Reproduced on:

 * A clean ''local'' WordPress install running WordPress '''6.9'''
 * Multiple production sites, showing the same behavior. The local
 reproduction confirms this is core behavior and not environment-specific.

 === Direct URL reproduction (most deterministic) ===

 Visit: `/wp-admin/upload.php?mode=grid&orderby=date&order=desc`

 Observe the ordering displayed in the grid.
 Control cases:

 * Works as expected:
  * `/wp-admin/upload.php?mode=grid&orderby=date&order=DESC`
  * `/wp-admin/upload.php?mode=grid&orderby=date`
 * Also triggers incorrect ordering:
  * `/wp-admin/upload.php?mode=grid&orderby=date&order=pizza`

 === Screenshots ===

 ** Incorrect Order: `order=desc` **
 [[Image(https://iili.io/fhBAuFs.png)]]

 ** Correct Order: `order=DESC` **
 [[Image(https://iili.io/fhBAAcG.png)]]

 === Common User Path (List Mode with Filters => Grid Mode) ===

 * Visit List mode with sorting: `/wp-
 admin/upload.php?mode=list&orderby=date&order=desc`
 * Click the ''Grid view'' toggle (the generated link preserves
 orderby/order).
 * Grid view renders the first batch of attachments in the wrong order.


 = Does the problem occur even when you deactivate all plugins and use the
 default theme? =

 Yes. Reproduced on a clean local install with:

 * Default theme (twentytwentyfive)
 * No plugins

 = What steps should be taken to consistently reproduce the problem? =
 ''Precondition:'' Media Library contains a few images where this sorting
 issue would be apparent.


 = What is the expected output or result? What did you see instead? =

 === Expected ===

 For: `mode=grid&orderby=date&order=desc` The grid should display
 attachments newest-first (DESC), consistent with server-side behavior and
 the AJAX response.

 === Actual ===

 With `order=desc` (lowercase) or invalid values such as `order=pizza`:

 The server-side query and the AJAX response contain attachments in the
 correct order (DESC by date).

 The Grid UI renders them reversed (appears ASC / oldest-first).

 This demonstrates the defect is ''not'' in `WP_Query` and not in SQL
 ordering; it is a ''client-side UI sorting issue'' in the Media Library
 grid JavaScript.


 = Please provide any additional information that you think we'd find
 useful. =

 * Tested primarily in Chrome on macOS (but this is browser-independent)
 * Grid view uses AJAX via `wp_ajax_query_attachments()` (admin-ajax). When
 reproducing, the network response data array arrives in the correct (DESC)
 order even when the URL contains lowercase/invalid order values.
 * Root cause appears to be a normalization mismatch: ** PHP / `WP_Query`
 normalizes order to uppercase (ASC/DESC) and defaults invalid values to
 DESC. ** Media grid JS uses a case-sensitive 'DESC' `===` order check;
 lowercase/invalid values fall through to the ascending branch and reverse
 the display order.
 * Relevant core code (6.9):
  * `wp.media.model.Query.prototype.filters.order`:
   * https://github.com/WordPress/WordPress/blob/6.9/wp-includes/js/media-
 models.js#L34-L76
  * `wp.media.model.Attachments.comparator`:
   * https://github.com/WordPress/WordPress/blob/6.9/wp-includes/js/media-
 models.js#L1092-L1112


 = Patch =

 Here's the patch:
 {{{
 --- a/wp-includes/js/media-models.js
 +++ b/wp-includes/js/media-models.js
 @@ -43,7 +43,7 @@ Query = Attachments.extend(/** @lends
 wp.media.model.Query.prototype */{

                this.filters.order = function( attachment ) {
                        var orderby = this.props.get('orderby'),
 -                              order = this.props.get('order');
 +                              order = ( this.props.get('order') || 'DESC'
 ).toUpperCase();

                        if ( ! this.comparator ) {
                                return true;
 @@ -1091,7 +1091,7 @@ var Attachments = Backbone.Collection.extend(/**
 @lends wp.media.model.Attachmen
         */
        comparator: function( a, b, options ) {
                var key   = this.props.get('orderby'),
 -                      order = this.props.get('order') || 'DESC',
 +                      order = ( this.props.get('order') || 'DESC'
 ).toUpperCase(),
                        ac    = a.cid,
                        bc    = b.cid;

 @@ -1108,7 +1108,7 @@ var Attachments = Backbone.Collection.extend(/**
 @lends wp.media.model.Attachmen
                        ac = bc = null;
                }

 -              return ( 'DESC' === order ) ? wp.media.compare( a, b, ac,
 bc ) : wp.media.compare( b, a, bc, ac );
 +              return ( 'ASC' === order ) ? wp.media.compare( b, a, bc, ac
 ) : wp.media.compare( a, b, ac, bc );
        },
        /** @namespace wp.media.model.Attachments.filters */
        filters: {
 }}}

 == What the patch changes ==
 The patch makes two small but important changes in wp-includes/js/media-
 models.js:

 === 1) Normalize order to uppercase in the media models ===
 It changes:
 {{{
 order = this.props.get('order');
 }}}
 and
 {{{
 order = this.props.get('order') || 'DESC';
 }}}
 to:
 {{{
 order = ( this.props.get('order') || 'DESC' ).toUpperCase();
 }}}

 So:

 'desc' becomes 'DESC'
 'asc' becomes 'ASC'
 undefined becomes 'DESC'
 'pizza' becomes 'PIZZA' (still invalid, but now handled consistently)
 This ensures the subsequent comparisons behave deterministically.

 === 2) Change the comparator to treat only explicit ASC as ascending
 (default everything else to DESC) ===
 It changes the comparator decision from:
 {{{
 return ( 'DESC' === order ) ? DESC_logic : ASC_logic;
 }}}
 to:
 {{{
 return ( 'ASC' === order ) ? ASC_logic : DESC_logic;
 }}}

 Effect:

 If order is exactly 'ASC', the Grid sorts ascending.
 For 'DESC' (and for any unexpected/invalid value), the Grid sorts
 descending.
 That default-to-DESC behavior matches how WP_Query behaves when order is
 missing or invalid, which prevents the UI from "flipping" the already-
 correct server ordering.

 == Testing Instructions ==

 Since this patch modifies the unminified JavaScript file `wp-includes/js
 /media-models.js`, to test it properly:

 1. Set `define( 'SCRIPT_DEBUG', true );` in your `wp-config.php` to ensure
 WordPress loads unminified JavaScript files instead of the minified
 versions (otherwise you need to rebuild or patch the minified file too.)
 2. Apply the patch to `wp-includes/js/media-models.js`.
 3. Clear your browser cache or use an incognito/private browsing window to
 avoid cached scripts.
 4. Follow the reproduction steps above to verify the fix:
    * Visit `/wp-admin/upload.php?mode=grid&orderby=date&order=desc` and
 confirm attachments display newest-first.
    * Test control cases: `order=DESC`, `order=asc`, and invalid values
 like `order=pizza` should all behave correctly (defaulting to DESC where
 appropriate).

 == Net Result ==

 * Grid view displays attachments in the same order as the AJAX response.
 * `order=desc` and `order=DESC` behave identically.
 * Invalid order values no longer cause the Grid UI to reverse the display
 order; they fall back to descending behavior instead.

-- 
Ticket URL: <https://core.trac.wordpress.org/ticket/64467>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform


More information about the wp-trac mailing list