The thing with upvar (and uplevel) is that by default upvar refers to variables in the caller of the current proc. But when a proc is called indirectly (e.g., a callback proc) then the variable upvar is intended to reference may be 2 or more frames above. Using something like "upvar #2 refvar var" works as expected. It's analogous to deferencing pointers in C when there are >1 levels of indirection.
Is there any programming language that doesn't have some confusing rules? If a language is going to be useful the answer is bound to be "no". It's a curious how we get used to a particular (or even peculiar) syntax. When used long enough it begins to feel "natural" and obvious, and find it amazing how anyone would have difficulty understanding how it works.