The problem must be how you define your post variable. You assume it’s the global $post
but that’s not always the case especially in non-singular pages like archives.
The filter itself provides the correct post instance that’s it’s been called on as 2nd parameter.
function product_type_permalink( $post_link, $post ) {
// current post is already defined.
...
}
Also don’t get confused by the fact your code is in functions.php
. It gets loaded on every WP page load, incl. in admin.