If you make a change to the return types of a function for example you have to manually find all of the different references to that function and fix the code to handle the change. Since there are no compile time errors it's hard to know that you got everything and haven't just caused a bug.
Especially with duck-typing, you might also assume that a function that previously returned true-false will work if it now returns a String or nil. Semantically they’re similar, but String conveys more information (did something, here’s details vs did(n’t) do something).
But if someone is actually relying on literal true/false instead of truthiness, you now have a bug.
I say this as a Ruby evangelist and apologist, who deeply loves the language and who’s used it professionally and still uses it for virtually all of my personal projects.
The best perspective I've seen is that statically typed enforcement is basically a unit test done at compile time.
Yes, and the downsides cascade. Because making any change is inherently risky you're kind of forced not to make changes, and instead pile on. So technical debt just grows, and the code becomes harder and harder to reason about. I have this same problem in PHP although it's mostly solved in PHP 8. But touching legacy code is incredibly involved.