How to save the option’s new values plus old value without overwrite old one

You are misspelling the variables names. You define them as $new_value and $old_value with underscore that you forgot about.

Except this your code working fine.

function myplugin_update_field_foo( $new_value, $old_value ) {
    if ($new_value !== $old_value && is_array($old_value)  && is_array($new_value)) {
        $new_value = array_unique( array_merge( $new_value, $old_value ) );
    }
    return $new_value;
}

To get the option you use

$opt = get_option( 'ra_new_series_options' );

You can set default value if not exists like this:

$opt = get_option( 'ra_new_series_options', [1, 3] );

Another thing that you need to make sure that the $new_value and the $old_value is type array because if one of them is not your code will break.

If you want to merge different types (array, string, integer) you can do something like this:

add_filter( 'pre_update_option_ra_new_series_options', 'myplugin_update_field_foo', 10, 2 );
function myplugin_update_field_foo( $new_value, $old_value ) {
    $new_value_array = [];

    // Check if array and merge if not push into the array
    if( is_array( $new_value ) ) {
        $new_value_array = array_merge( $new_value_array, $new_value );
    } else {
        array_push( $new_value_array, $new_value );
    }

    if( is_array( $old_value ) ) {
        $new_value_array = array_merge( $new_value_array, $old_value );
    } else {
        array_push( $new_value_array, $old_value );
    }

    $new_value_array = array_unique( $new_value_array );

    return $new_value_array;
}

tech