when trying to set value of the projectMatrix, I got an invalid operation error, what I’ve missed?

...
auto loc = glGetProgramResourceLocation(prog,GL_UNIFORM,"projectMatrix");
GLfloat proj[16] = {0};
glGetFloatv(GL_PROJECTION_MATRIX,proj);
// I'm sure loc is valid
// and prog has linked successfully
glProgramUniformMatrix4fv(prog,loc,16,false,proj); // invalid operation
...

This says that you’re uploading to an array of 16 4x4 matrices. You aren’t; you’re only uploading to an array of one 4x4 matrix. The size parameter is the number of 4x4 matrices; the fact that you’re calling the Matrix4fv version of the function is how it knows that each matrix is 16 floats.