A custom WP_Query loop with AJAX-based sorting works correctly for one post type but produces wrong order for another. The sort arguments look right. The most common cause is a third-party plugin — specifically one that overrides the default post order at the database level.
Problem: A filtered archive page uses AJAX to re-run a WP_Query with custom sort parameters, but the results return in the wrong order — the orderby argument appears to be ignored.
Solution: Log the query arguments server-side before the query runs to confirm what is actually being passed. The most common causes are a third-party plugin's posts_orderby filter overriding the order, or $_POST values not matching the expected parameter names in the AJAX handler.
Start by verifying your query arguments are correct. Log them before the query runs:
$args = [
'post_type' => 'portfolio',
'orderby' => 'date',
'order' => 'DESC',
'meta_key' => '', // must be empty if not ordering by meta
];
// Debug — log the final args (remove before deploying)
error_log( print_r( $args, true ) );
$query = new WP_Query( $args );
If the args look correct, check whether the Intuitive Custom Post Order plugin (or a similar plugin) is active. These plugins hook into WordPress queries and inject a custom menu_order-based sort for the post types they manage:
wp plugin list | grep -i order
Disable ordering for the affected post type in Settings → Intuitive CPO, or exclude your custom query from the plugin's override using its filter:
// Prevent Intuitive CPO from modifying sort on custom AJAX queries
add_filter( 'ICPO/StopModification', function( $stop, $query ) {
// Stop modification on queries that already specify an orderby
if ( ! empty( $query->get( 'orderby' ) ) && $query->get( 'orderby' ) !== 'menu_order' ) {
return true;
}
return $stop;
}, 10, 2 );
NOTE: A reliable way to confirm a plugin is causing the sort conflict is to deactivate it temporarily and test the query again. If the sort becomes correct, that plugin is responsible. Rather than disabling the whole plugin, disable it only for the post types where you need programmatic sort control — most order plugins provide per-post-type settings in their admin screens.