The fact that a change passed a CI and another change passed a CI doesn't mean they can merge and the result is guaranteed to pass CI. It will often break and if you think for a minute you will come up with really rudimentary examples of this.
The really primitive solution is to call the merge-recipient branch the "develop" and only merge to "master" when you are sure what you are merging is good. You'll be ok if you do it sequentially (no parallel merges to master).
A more complicated solution is to actually test (in CI) "what happens when I merge this" but in hiding, without showing it to others. Even more complicated is to do it in parallel. Gitlab calls it Merge Trains (Premium only). Zuul-CI calls it gate/gating and has a pretty good description here: https://zuul-ci.org/docs/zuul/discussion/gating.html#testing...