"here's the interesting part: at the end of my delete function, i return the successor node (referred to as $curr). if i have a receiver for the returned $curr node outside of my program, everything works fine."
Within RBDelete, you're telling $node's parent to point to $curr. $curr is local to RBDelete. If you don't store the-node-formerly-known-as-$curr outside the scope of RBDelete by capturing the return value, the parent of your deleted node will be pointing to undef.