How to only allow post to be deleted if custom field doesn’t exist

You can hook into before_delete_post and redirect before completing the deletion.

add_action('before_delete_post', function($post_id) {

   // Get custom field
   $field = get_post_meta( $post_id, 'key', 'true');

   // Redirect if field is empty
   if (!$field) {
       wp_redirect(admin_url('edit.php'));
       exit();
   }

}, 1);