Your problem might be auto-vivification. With defined, you just check if a value of a hash is defined, not if it is existing. (And the value of a hash may be existing but undef without problems).
Better use something like:
if( exists($foo->{$_} and exists($foo->{$_}->{bar} ) {
...
}