Работающее решение проблемы. Если тип поста отличается от дефолтных, но он не найден, проверяем, существует ли страница с таким адресом.
function loop_cpt_filter($wp_query) {
// Variables
$post_slug = null;
$query_vars = $wp_query->query_vars;
// If CPT is set but post not found
if(!$wp_query->post_count && isset($query_vars['post_type'])) {
$post_type = $query_vars['post_type'];
$cpt_object = get_post_type_object($post_type);
if(isset($query_vars[$post_type])) {
$post_slug = trim($cpt_object->rewrite['slug'] . '/' . $query_vars[$post_type], '/');
}
// If page by that slug exists, set post to the current query
if($post_slug && ($page = get_page_by_path($post_slug))) {
$wp_query->set('post_type', 'page');
$wp_query->set('p', null);
$wp_query->set('page_id', $page->ID);
}
}
}
add_action('pre_get_posts', 'loop_cpt_filter', 100, 1);