Algorithm negotiation within an otherwise static protocol incurs complexity, which has a security cost. Just as importantly, it doesn't address the real origin of cryptographic protocol flaws. Note how, in order to correct cryptographic flaws in TLS, we had to push people first from SSL3 to TLS 1.0, and then later to TLS 1.1.
1. "Hard-code" the simplest possible sound crypto construction that solves the specific problem the protocol is meant to solve.
2. Put a version on the whole protocol.
3. If the crypto constructions later need to be amended, upgrade the whole protocol.
The anti-pattern is attempt to use a static "outer protocol" with a negotiated and regularly changing "inner protocol" --- that's an architecture we know from experience does not work well.
You know you're in trouble when developers are forced or even encouraged to make decisions between things like RSA and ECC.