Dynamic languages work out great when code coverage is ~100% at every run, and runs are short.
Virtually all programs start out that way, so dynamic languages feel great.
As they grow, the pain creeps in very slowly. As you said, by the time the programmer realizes he's in hell, it's too late to fix it.