wp_query – Exclude the first thumbnail from lazy loading on archives

Filters must always return a value. If you do not return a value, it’s the same as returning an empty value, null, etc. This is always the first parameter, or a modified/replacement version of it.

So this:

add_filter( 'wp_get_attachment_image_attributes', function( $attrs ) {
    if ( !is_single() && !is_page() && is_front_page() && is_archive() && is_search() ) {
        global $wp_query;

        if ( $wp_query->current_post === 0 )
            $attrs['loading'] = 'eager';
            return $attrs;
        }
    }
);

Is the same as this:

add_filter( 'wp_get_attachment_image_attributes', function( $attrs ) {
    if ( !is_single() && !is_page() && is_front_page() && is_archive() && is_search() ) {
        global $wp_query;

        if ( $wp_query->current_post === 0 )
            $attrs['loading'] = 'eager';
            return $attrs;
        } else {
            // I don't want post thumbnails, return nothing
            return null;
        }
    }
    // I don't want post thumbnails, return nothing
    return null;
);

Remember, a filter is WordPress handing you a value temporarily, then you handing it back to WordPress, allowing you to change it.

What your code does is the equivalent of handing it back with a change if it meets certain criteria ( changing lazy to eager ), but if it doesn’t meet those criteria instead of handing it back unchanged, you’ve set it on fire and thrown it away.

If we add type hinting to the function, it make the mistake more obvious with a PHP fatal error:

add_filter( 'wp_get_attachment_image_attributes', function( $attrs ) : array {

The function needs to return a value, and by doing this we tell PHP it always returns an array. As a result when a post that is not the first post, or a page that is not a search archive etc loads, the function doesn’t return anything and it will generate a PHP fatal rather than a warning.

You should also have noticed that the PHP error log will contain PHP warnings for this function.

To fix this, you need to change the filter so that it always returns a value. You get no post thumbnails because the filter return nothing. If you don’t want to change the attributes, return them as is with return $attrs;. Filters always return something

tech