I've had varying 'experiences' with CGI::Session, and at some point added the following code to my CGI::Application teardown() routine:
# Force CGI::Session flush now (rather than wait until object
# destruction time when any errors/messages may be lost to us.
$session->flush()
or die "Unable to update session storage\n";
Try again using a global for the $session object handle, but use the flush() method at the end of all your processing. You may solve the problem right there, or generate an error message that will lead you to a definite problem.