Component deleted before detach assertion OpenGL, even after detaching before destroying

class OpenGLComponent 
    : public Component,
      public OpenGLRenderer
{
public :

    OpenGLComponent(){
    opengl_context.setOpenGLVersionRequired(OpenGLContext::OpenGLVersion::defaultGLVersion);

    opengl_context.setRenderer(this);

    opengl_context.setComponentPaintingEnabled(false);
    opengl_context.setContinuousRepainting(false);
    
    opengl_context.attachTo(*this);
}
    ~OpenGLComponent(){
    opengl_context.detach();

    shader.reset();
    shader_uniforms.reset();
}

    // ================================================
    void newOpenGLContextCreated() override{
    createShaders();

    opengl_context.extensions.glGenBuffers(1, &VBO);
    opengl_context.extensions.glGenBuffers(1, &EBO);

    send_triggerRepaint = true;
    opengl_context.triggerRepaint();
    }
    void renderOpenGL() override{
    ....
    }
    void openGLContextClosing() override{
    send_triggerRepaint = false;

    if (VBO != 0)
    {
        opengl_context.extensions.glDeleteBuffers(1, &VBO);
        VBO = 0;
    }
    if (EBO != 0)
    {
        opengl_context.extensions.glDeleteBuffers(1, &EBO);
        EBO = 0;
    }

    shader.reset();
    shader_uniforms.reset();

}

    // ================================================
    void paint(Graphics& g) override {};
    void resized() override {};

    OpenGLContext opengl_context;
private:
    const char* vertexShader, fragmentShader ;

    struct Uniforms
    {
    public:

        Uniforms(
            OpenGLContext& OpenGL_Context,
            OpenGLShaderProgram& shader_program);

        std::unique_ptr<OpenGLShaderProgram::Uniform> phase_correl_data, resolution;

    private:

        static OpenGLShaderProgram::Uniform* createUniform(
            OpenGLContext& gl_context,
            OpenGLShaderProgram& shader_program,
            const char* uniform_name
        );

    };

    GLuint VBO = 0, EBO = 0;

    std::unique_ptr<OpenGLShaderProgram> shader;
    std::unique_ptr<Uniforms> shader_uniforms;


    void createShaders();

};

It hits this assertion even though i detach in the destructor before the component gets destroyed :

 void componentBeingDeleted (Component& c) override
 {
     /* You must call detach() or delete your OpenGLContext to remove it
        from a component BEFORE deleting the component that it is using!
     */
     jassertfalse;

     ComponentMovementWatcher::componentBeingDeleted (c);
 }
#endif

Some kind of data race ? because of the different threads or am i missing something. please let me know if any more information is needed.

Is that the only OpenGLContext in your application? The context is a public data member - is there any chance you’re accidentally calling attach() or detach() on that object somewhere else (e.g. from the parent component)? What’s the full call stack at the point of the assertion?

Thank you for the reply, I’ve fixed it. the parent does not own the component but it is added as child. The component is getting double deleted when the program quits. After I remove the respective components a children from the parent the assertion was no longer getting hit.

And another question regarding open GL renderer, setting this

opengl_context.setContinuousRepainting(false);

doesn’t seem to stop the component from continuously getting repainted. Is there any way we can trigger the repaint for opengl_context like we call repaint() on a normal Component ? I’ve seen

opengl_context.triggerRepaint();

but I couldn’t use it as the component is continuously getting repainted anyways.