Am unable to reset a query properly

wp_reset_query is for cleaning up after a query_posts call, you don’t need to call it after a standard posts loop, only if you use query_posts. Since you should never use query_posts to fetch posts from the database, you should never use this function.

But How Do I Cleanup After The Main Loop?

You don’t, this is an example of a full main post loop:

if ( have_posts() ) {
    while ( have_posts() ) {
        the_post();
        // display content
    }
} else {
    // none found
}

What About WP_Query or get_posts?

There’s a similar and more useful function named wp_reset_postdata. This function cleans up after these functions:

  • WP_Query::the_post
  • setup_postdata

So an example of a WP_Query post loop should look like:

$q = new WP_Query( [ ... ] );
if ( $q->have_posts() ) {
    while ( $q->have_posts() ) {
        $q->the_post();
        // display content
    }
    wp_reset_postdata();
} else {
    // none found
}

Notice that I called wp_reset_postdata after the while loop, but inside the if statement, not after it. Only reset postdata if there’s something to clean up

And If I Need To Override The Loop?

Use the pre_get_posts filter to modify the main loop, don’t create a new replacement query.

What About get_posts?

If you never set the postdata, then you never have to reset it.