According to the CGI documentation (under "CREATING FILL-OUT FORMS"), you have to tell it that you really mean for the parameter to be what you asked it to be. (I have found this behavior annoying frequently, but it is documented.)
use CGI;
my $cgi = CGI->new();
$cgi->param( 'mode', 'orig' );
print $cgi->hidden( 'mode', 'second arg' ), "\n";
print $cgi->hidden( -name => 'mode',
-default => 'default', ), "\n";
print $cgi->hidden( -name => 'mode',
-default => 'forced',
-override => 1 ), "\n";
__END__
<input type="hidden" name="mode" value="orig" />
<input type="hidden" name="mode" value="orig" />
<input type="hidden" name="mode" value="forced" />