I just solved a really hard bug today at work. I was receiving the error GL_INVALID_OPERATION on a glEnd() or glDrawBuffers. This was due to one of our textures that was not unbound to the correct target. We had a 2D texture that was bound to the unit 0 at the target GL_TEXTURE_2D. Then later, we had another texture bound also at unit 0 but in target GL_TEXTURE_3D. This was the cause of the problem. If you do this:
glBindTexture(GL_TEXTURE_3D, texture2); // PROBLEM
It will raise a GL_INVALID_OPERATION. The correct way to do is:
// some code
glBindTexture(GL_TEXTURE_2D, 0); // unbind the texture
If you look at the official documentation of glBindTexture, nothing explains that not unbinding the texture in the previous target will raise this error. I think they should be more specific on this issue.
And the really bad thing is, you will have a GL_INVALID_OPERATION only if you use the associated unit and when you order the drawing with glEnd() or glDrawArrays which is in a totally different place in my program, so going back to the origin of the problem is really painful and long.
Personnally I would prefer an error directly when I try to bind to a different target and I didn’t yet unbound to the previous target… Or even better, just forget about the previous target and the new target just override it. At least it would have saved me two days…