I would guess that this has something to do with a string's reference type nature.
I've known about this but I don't think I ever mentioned it outside of chat.
I guess string literals are read-only, though it's weird...
If you do A$=B$, A$ and B$ will be the same string. But TEST$="Z" must actually make a copy, otherwise your second example would throw the same error.
Anything set inside a function that doesn't output stuff revert to the previous value when the function is ended unless it's an array value.
I thought this was common knowledge for SB coders...