Gitlab CI is 3-4 different systems on top of each other wearing a trenchcoat. Every so often, they realise they can do CI better and come up with a new syntax for everything (see stages, which got extended by dependencies, which got superceded by the needs mechanism, or only/except which got replaced by rules). Obviously, they can't easily remove the old syntax, so pipelines very quickly become a mix of different mechanisms, some old, some new, with weird, unpredictable, and usually poorly documented interactions between them. You can try and only use a restricted subset of well-defined Gitlab CI, but part of the problem with modern DevOps is that most developers are not very experienced with the CI syntax, and will just find snippets on SO that do what they want and leave it there.
Apart from that, the documentation overall tends to be very poor, and the implementations are often buggy or missing functionality (a lot of searches for "Gitlab CI <thing I want to do>" would just link to an open ticket in the Gitlab repo describing exactly the functionality I needed, and dozens of comments going "yeah, this is necessary" and "a silver level customer needs this functionality to continue using Gitlab"). There's also lots of stuff that relies very heavily on being and to configure everything in YAML. other CI systems also have this problem, but often provide mechanisms to write individual tasks in other languages so you distribute, say, the "deploy this Docker image to our k8s cluster" task as a standalone unit written, tested, and reviewed in a real programming language. Gitlab CI has a very basic version of this feature, except it's still all in YAML, it's almost impossible to test, and it's very difficult to configure these tasks at all.
Fwiw, I've done plenty with Gitlab CI, and it's not like it doesn't work. It is perfectly fine if you don't have particularly complex needs, and the runners mechanism seems fairly easy for system administrators to get started with and get working. But overall, the whole system feels only half thought-through, and trying to do anything complex tends to require a lot of hair-pulling and confusion.