It's not necessarily the language itself, which is a reasonable language, it's the patterns that are common in the ecosystem:
1. Use of inheritance for code sharing. It makes it extremely hard to reason about any piece of code I am looking at. Where does the `param` variable come from? Is it injected by any ancestors of the class I'm looking at? Who knows, I have to use the debugger to find out. I cannot reason about the code without it. Of course you can use Ruby while preferring composition over inheritance, it's just rarely done by the community. Other modern languages like Go and Rust wisely leave out inheritance for code sharing in their object model and arguably have much more readable (albeit verbose) code.
2. Global mutable state is everywhere. Not sure if it's Rails architecture that encouraged using global state as request local state (until they found out that this makes concurrency hard), but Ruby codebases are full of global mutable state. It's everywhere and again makes it hard to reason about dependencies between objects and how they interact with each other. Again, this is nothing that the language forces people to do, it's conventions.
3. Overuse of meta programming. Ruby's metaprogramming is really well done in my opinion. The problem is that lots of people want to use it and do so in places where it doesn't provide enough value to justify the costs. It's an authentication library. It doesn't need it's own DSL.