If you have defined "remove = 1" in your config, then Log::Message's retrieve method ( called by methods such as final ) will consume messages. When you call final at line 32, the messages have already been consumed by prior retrieves, the stack is empty, and it returns undefined. The chain to croak is effectively "do { undef }->croak", triggering the error you report.

There are various ways this could be managed when remove = 1 i.e. checking if defined, retrieving all into a list etc. Otherwise set the remove config attibute to 0.

Also, I have an off-topic question: Why are there two config files that are needed? I set them both to the same file for now but I don't understand why it would need to different configuration files?

Providing config attributes on use sets the default attributes on new. This is useful if you are creating more than one Log::Message object which share some of the same attributes, but not others. I personally don't like the use / import interface, and would just provide all of the attributes on new. it provides clarity and doesn't cause issues later if multiple instances across multiple scripts ( default config is stored in a global package variable! ).