It looks as though the browser isn't sending the data as UTF-8 unless it contains text that has to be. As soon as I add a € or some other character that's utf-8 it comes through fine.
I've never seen any browser send anything but UTF-8 if the page was marked as UTF-8.
my $decoder = Encode::Guess->guess($v);
Try to get rid of Encode::Guess, just use Encode::decode_utf8() or utf8::decode(). Guessing isn't necessary for normal browser input, and can only add problems by mis-guessing.
Dealing with UTF-8-flagged strings in Perl can be very complicated and error-prone, but in my experience, it works when handled correctly.