As pointed out by @cscott on a mastodon post:
@bvibber hm, be careful. The target language is 'zh' because it is going to be language converted. The *user* language is zh-whatever, because messages are pre-localized and don't go through language converter. You risk corrupting the parser cache if you mix those two together. I think you should be using getUserLanguage() which will also tag the parser output as being dependent on user language.
Fix here should be to call getUserLanguage() even though we actually want the target language, because we need to mark the page as being dependent on the user language's variant selection. This probably should only happen if the target language and user language base languages match, to avoid the extra cache fragmentation on non-variant content languages.
Worst case if we don't fix this is parsercache corruption saving/displaying the wrong variant on Chinese, Serbian etc.