In version 3.1 WordPress began enforcing a restriction…

In version 3.1, WordPress began enforcing a restriction against using is_page(), and other conditional functions that leverage $wp_query, before the init action. Prior to version 1.5, BuddyPress was one of the violators of this restriction – BP’s global- and navigation-setup routines, which required reference to $wp_query, were hooked to plugins_loaded, well before init. This transgression was corrected in r3742, where the main BP hooks (bp_setup_globals, bp_setup_nav, and the like) were switched from plugins_loaded to init. See #2609 for further discussion.

What does this mean for BuddyPress plugins and themes? The good news is that the change will be invisible and seamless for most. However, the change in load order does have some implications for functions like bp_core_remove_nav_item() and other functions that only work properly once the global- and navigation-setup routines are finished. That’s because, with the switch to init, your plugin files as well as your theme’s functions.php are now loaded before BP sets up its globals and nav.

In practical terms, BP 1.2.x erroneously allowed you to put the following line directly into a plugin file or functions.php, into the global scope:

bp_core_remove_subnav_item( 'activity', 'friends' );

This will no longer work. Modifications to BP navigation should be done inside of a function hooked to bp_setup_nav, with the priority of 10 or higher. So the previous code becomes:

function bbg_remove_activity_friends_subnav() {
    bp_core_remove_subnav_item( 'activity', 'friends' );
}
add_action( 'bp_setup_nav', 'bbg_remove_activity_friends_subnav', 15 );

Likewise, any modifications to the $bp global should be hooked to bp_setup_globals.

See #3438 for more discussion. Many thanks to sbrajesh for raising the issue.