Why is my array_diff usage breaking things?

You’re getting the Fatal Error because array_diff() is comparing the WP_Term objects in your array to a string, and it can’t do that. Here’s one way to fix that:

Replace

$topic = array_diff($topic, ["expired"]);

with:

$my_topic = array();
foreach ( $topic as $term ) {
    if ( 'expired' !== $term->slug ) {
        // Adds $term to my topic if it's not 'expired'.
        $my_topic[] = $term;
    }
}
// $my_topic is the new $topic.
$topic = $my_topic;