BuddyPress activity queries ignore your WP_Query habits

The activity stream is not posts. It has its own table, its own class and its own template loop, so every habit built around WP_Querypre_get_posts, fields => ids, the post and meta caches, meta_query — applies to none of it, and the arguments are quietly ignored rather than rejected.

// none of these mean anything: activities are not a post type
new WP_Query( array( 'post_type' => 'activity', 'posts_per_page' => 20 ) );

// the API that exists
if ( bp_has_activities( array(
    'per_page'         => 20,
    'page'             => 1,
    'scope'            => 'groups',
    'user_id'          => $user_id,
    'filter'           => array( 'action' => 'activity_update' ),
    'display_comments' => false,
) ) ) {
    while ( bp_activities() ) { bp_the_activity();
        echo bp_get_activity_content_body();
    }
}

Pagination is per_page and page; max caps the total rather than the page, which is the argument to reach for on a widget that should never show more than ten items. display_comments defaults to threaded, and threading costs an extra query per top-level item plus the assembly on top — turning it off is the single largest saving available on a sidebar stream. Structured filtering is limited to what the filter array accepts: action, object, the two id fields and user id. Anything beyond that means calling BP_Activity_Activity::get() and writing the clause yourself, at which point you are writing SQL against bp_activity and the comment should say so.