This problem is giving me a headache and I was wondering if anyone knew how to fix it.

I have a custom post type called Review. Here is how it is defined:

function codex_custom_init() {
    $args = array( 'rewrite' => array('slug' => 'review'), 
                    'public' => true, 
                    'has_archive' => true, 
                    'show_ui' => true,
                    'label' => 'Review', 
                    'publicly_queryable' => true,
                    'taxonomies' => array('category', 'post_tag'), 
                    'supports' => array( 'title', 'editor', 'comments', 'excerpt', 'custom-fields', 'thumbnail', 'author')
    register_post_type( 'review', $args );

add_action( 'init', 'codex_custom_init' );

My archive page, handled by archive-review.php, works fine for pages like this


However, when categories are involved, wordpress does not display the "next" page. Instead, it goes to a 404. For example, when I try to access this:


Why does that give a 404? Also, it no longer is powered by archive-review.php, but archive.php (which makes sense I guess)

archive.php query stuff:

$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
        $cat = get_category(get_query_var('cat'));
        $catID = $cat->term_id;
        $args = (array('post_type' => array('post', 'review'), 'cat' => $catID, 'paged' => $paged));

Please help!! I am very frustrated!

  • http://www.acme.com/category/random/page/2/ is random a typo?
    – vancoder
    Aug 6, 2013 at 17:52
  • @vancoder random is the category slug in this example
    – 21zna9
    Aug 6, 2013 at 19:03
  • @toscho I will try it with creating a new wp_query as the example i've seen on CSS Tricks, but I'm not sure why that would make a difference as this is the "main" query loop and therefore query_posts() should be applicable...
    – 21zna9
    Aug 6, 2013 at 19:04
  • Simple but important, did you flush your permalinks? Aug 6, 2013 at 19:30

1 Answer 1


Creating a secondary query or overwriting the main query inside a page template is the quickest and easiest way I know to break pagination.

The main query, which determines which page to load runs before your template thus the results on the page and the query that loads the page become out of sync. The main query does not know about your in-template modifications to the query. It doesn't matter that your in-template query modifies the "main" query. The changes come too late.

What you need to be doing is use a filter on pre_get_posts. Unless I am reading it wrong, all you need to do is set the post_status.

function set_post_type_for_archive_wpse_109213($qry) {
  if ($qry->is_archive()) {
    $post_type = $qry->get('post_type');
    if (empty($post_type)) {
      $post_type = array('post');
    $post_type[] = 'review';
    $qry->set('post_type',  $post_type);

Unless you are the WordPress Core, and you aren't, query_posts is never applicable. Just don't use it.

  • Don't know why @21zna9 didn't accept this answer. This answer helped me. +1 for s_ha_dum
    – IFightCode
    Jan 14, 2014 at 12:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.