the_post_thumbnail() returns nothing even though has_post_thumbnail() returns true

You’re passing an invalid argument to the_post_thumbnail().

Here’s your code: the_post_thumbnail($post_id);

Here’s what the_post_thumbnail() expects: the_post_thumbnail( $size, $attr );

The function is expecting a $size as the first argument. Since $post_id is not a valid $size, the function doesn’t know what to output.