I appreciate your quite comment on this.
Indeed it was an issue with the header_remove lines in the virtual domains router.
I read around and someone suggested doubling the colons as the list items are now processes separately. I did exactly that and it worked like a charm.
virtual_domains:
driver = redirect
allow_fail
data = ${lookup mysql{select smtp from users,domains \
where localpart = '${quote_mysql::$local_part}' \
and domain = '${quote_mysql::$domain}' \
and domains.enabled = '1' \
and users.enabled = '1' \
and users.domain_id = domains.domain_id}}
headers_add = ${if >{$spam_score_int}{${lookup mysql{select users.sa_tag * 10 from users,domains \
where localpart = '${quote_mysql::$local_part}' \
and domain = '${quote_mysql::$domain}' \
and users.on_spamassassin = '1' \
and users.domain_id=domains.domain_id }{$value}fail}} {X-Spam-Flag: YES\n}{} }
headers_remove = ${if or { { <{$spam_score_int}{1} } \
{ <{$spam_score_int}{${lookup mysql{select users.sa_tag * 10 from users,domains \
where localpart = '${quote_mysql::$local_part}' \
and domain = '${quote_mysql::$domain}' \
and users.on_spamassassin = 1 \
and users.domain_id=domains.domain_id}{$value}fail}} } \
{ eq {0}{${lookup mysql{select users.sa_tag * 10 from users,domains \
where localpart = '${quote_mysql::$local_part}' \
and domain = '${quote_mysql::$domain}' \
and users.on_spamassassin = 0 \
and users.domain_id=domains.domain_id}{$value}fail}}} \
} {X-Spam-Score::X-Spam-Report} }