How to add a post or page tag to the list of classes appearing in the body tag’s class attribute?

You’re close. Your first attempt is using get_the_tags incorrectly. The function accepts the post ID you want to get the tags from. In your example, there is no $tag global, so $tag->name is trying to fetch a property of a non-object.

In your second attempt, a single post won’t have any tag-related query vars, that would only be set on a tag archive page (also, the tag taxonomy is actually named post_tag behind the scenes).

So here’s a working version that fixes the issues with your examples. Note that we use get_queried_object_id() to pass the current post/page ID to get_the_tags(). You may see other examples that use global $post and then $post->ID to pass the ID to functions, this would also work.

function add_tags_to_body_class( $classes ) {

    // if this is a page or a single post
    // and this page or post has tags
    if( ( is_page() || is_single() )
        && $tags = get_the_tags( get_queried_object_id() ) ){

        // loop over the tags and put each in the $classes array
        // note that you may want to prefix them with tag- or something
        // to prevent collision with other class names
        foreach( $tags as $tag ) {
            $classes[] = $tag->name;
            // or alternately, with prefix
            // $classes[] = 'tag-' . $tag->name;
        }
    }

    // return the $classes array
    return $classes;

}
add_filter( 'body_class', 'add_tags_to_body_class' );