Category with post type pagination returns 404

I found a solution!

I was able to find a function that modified the query on the category page (https://wordpress.org/support/topic/custom-types-category-pagination-404/#post-1913902 – on the first page toward the bottom, written by: Mark / t31os).

Add this to functions.php:

add_action( 'parse_query','changept' );
function changept() {
    $category = get_query_var('cat');
    $paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
    if (is_category() && !is_admin())
        set_query_var( 'cat', $category );
        set_query_var( 'paged', $paged );
        set_query_var( 'posts_per_page', 9 );
        set_query_var( 'post_status', 'inherit' );
        set_query_var( 'post_type', 'attachment' );
    return;
}

This is what category.php looks like now:

<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
    <a href="https://wordpress.stackexchange.com/questions/275497/<?php the_permalink(); ?>"><?php echo wp_get_attachment_image($image->ID, "medium"); ?></a>
    <h5><?php the_title(); ?></h5>
    <?php
        $attachment = get_post(get_post_thumbnail_id()); // Get post by ID
        echo '<p>'.$attachment->post_content.'</p>'
    ?>
<?php endwhile; endif; ?>
    <ul class="pagi">
        <li><?php posts_nav_link(' | ','< Previous','Next >'); ?></li>
        <li><?php echo "(Page: ". $paged . " of " . $wp_query->max_num_pages .")"; ?></li>
    </ul>

UPDATE:

I ran into a problem with my solution…it was executing on all the pages. All pages except the category page were returning a 404, So I needed to run the code only on the category page to fix the issue.

Here is the updated code functions.php:

$url = $_SERVER['REQUEST_URI'];
if (strpos($url,'category') !== false) {
    add_action( 'parse_query','changept' );
    function changept() {
        $category = get_query_var('cat');
        $paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
        if (is_main_query()) {
            set_query_var( 'cat', $category );
            set_query_var( 'paged', $paged );
            set_query_var( 'posts_per_page', 9 );
            set_query_var( 'post_status', 'inherit' );
            set_query_var( 'post_type', 'attachment' );
        }
        return;
    }
}

Basically, this checks to see if the word “category” is part of the url, and because I am only using this on my category.php page, this will work without affecting any other page. There is probably a better solution out there, but this works for my project. Also, another if was added to target the main query: is_main_query()…this way if you have other queries on the page, they will still function normally.

I’m sure you can do something similar with pre_get_posts, which is Milo’s suggestion, but I just couldn’t figure out how to use that function with my template.