I found the culprit!

I was rendering everything to an offline FBO, then at the end of the render call made a blit to the default FB, so called offline rendering.
When blitting, I put the default FB as draw, and the FBO as read. I did not change back until after glfwSwapBuffers.
So, my theory is that discord hooks itself into the swapbuffers call and when it's triggered, it reads the FB bound to read, which was my FBO, and that didn't work well.
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
did the trick after the blit. Can be worth mentioning that swapbuffers can have this behaviour.
Now I'm only left with
[LWJGL] OpenGL debug message
ID: 0x500
Source: API
Type: ERROR
Severity: HIGH
Message: GL_INVALID_ENUM error generated. Operation is not valid from the core profile.
Which happens the second I start streaming. I can't catch it with glGetErrors though, it's vanished.
Removing these hints solves that problem:
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
It is not enough to simply remove the GLFW_OPENGL_CORE_PROFILE one, even though the error output suggests it.
I'm not sure why I specify these hints. I guess it's because I'm using >= 3.3 features, but other from that I'm not sure about the benefit, I just want my app to be as compatible as possible. I can check through glCapabilities if 3.3 is supported.
Ah, now I remember, to make it work on Mac...