Ok, I think I figured out what's going on here. Luke is using interpreted splices. In 0.10, all of the built-in splices became load time splices. Load time splices are like interpreted splices except they are processed at load time before anything else happens. I had to do it this way because it turns out that the composable nature of interpreted/load-time splices is crucial to getting the expected behavior of the built-in splices. They can't work as compiled splices, so I set the Heist snaplet to bind them as load time splices by default. This is the correct thing to do when you're using compiled splice mode. However, when you're using interpreted mode you don't need this because you can just make them be interpreted splices.
The bind is getting bound even when the body of dfIfChildErrors is not executed because the bind splice is being processed as a load time splice. I believe this will be fixed if the heist initializer is changed to the following:
nestSnaplet "heist" heist $ heistInit' "templates" $ mempty { hcInterpretedSplices = defaultInterpretedSplices }