Thanks all for the quick replies. I don’t mean to ignore all of your helpful questions and suggestions, but those may not be needed anymore.
After getting a chance to speak with a colleague who’s been out of the office for a while, I was able to identify the problem here. A function from a custom plugin was filtering both the bp_before_has_activities_parse_args and bp_after_has_activities_parse_args filters, and the specific problem was that it was setting $args['include'] to an empty string. This removed the comment ID that was supposed to be part of the query, and resulted in the wrong query. We don’t know why it was doing this in the first place, but it has been corrected and the infinite loop has been fixed.
Regardless, it may be beneficial to include some checking in this code to prevent the possibility of an infinite loop even for edge cases like this.