In 90% of the cases, that is refreshing the same page, functions wp_list_comments(), comments_form(), has_comments() and other functions alike aren't yielding the expected results.
So I refresh the same page and these functions return different results, for example either 0 comments, 5 or 21 comments, while no other user is using the database since it's a test system with XAMPP. It's noticeable that only values 0, 5 and 21 seem to pop up for the numer of comments.
Looking further down the call stack I could notice that sometimes $wpdb->has_comments() returns 0 although the post contains comments.
I suspect this may be something related to wordpress caching system of my version 4.5 and the only issue I found on their bug tracker was related to including wp_list_comments() twice in the same file, which is not the case. Updating to latest version also does not solve this.
I have noticed that the below debug log was printed in the debug.log file, but only once although the page has been reloaded hundreds of times:
WordPress database error You have an error in your SQL syntax; check the
manual that corresponds to your MariaDB server version for the right syntax to
use near 'WHERE AND comment_parent IN (61,62,66) ORDER BY comment_date_gmt
ASC, comment_' at line 1 for query WHERE AND comment_parent IN (61,62,66)
ORDER BY comment_date_gmt ASC, comment_ID ASC made by
content\themes\mytheme\single.php'), get_template_part, locate_template,
load_template, <...more files here...>, comments_template,
WP_Comment_Query->__construct, WP_Comment_Query->query, WP_Comment_Query-
Issue occurs on multiple self-hosted wordpress installations.
With other themes, like twentysixteen or others I don't see this sort of behavior, so it's definitely something wrong on my side and I suspect the caching configuration, which I didn't touch.
Also, I've checked for wp_reset_postdata() usage and there's none in my single template. Add theme support is used for comments and everything. Any hint or some direction in which I should dig further would be great!
Found out what the issue was.
Somewhere in the code, in the middle of THE MAIN LOOP a file was included with get_template_part() and in that file a function running a new WP_Query was missing wp_reset_postdata(). This caused the global $post to become corrupt, at least from my point of view.
Since that WP_Query was used to get a random post, this caused comments to be shown for that random post. Sometimes they existed, other times they didn't.
Also, further functions like get_next_post() and get_previous_post() that were relying on $post were now returning results relative to the new random post instead of the old post, as expected.
Only when I noticed these adjacent functions were returning invalid results did I understand where the issue was.