Impossible to invoke a message inside of a timer app? it is impossible for me to invoke a message within a timer app, is it normal? or is it a bug?

for this message system:

import bpy 

def ShowMessageBox(message = "", title = "Message Box", icon = 'INFO'): #Message function
    def draw(self, context):
        self.layout.label(text=message)
    bpy.context.window_manager.popup_menu(draw, title = title, icon = icon)

ShowMessageBox("Such crash", "Many Wow" ,"BLENDER")


if i put him inside any blender timer app loop

import bpy 

def ShowMessageBox(message = "", title = "Message Box", icon = 'INFO'): #Message function
    def draw(self, context):
        self.layout.label(text=message)
    bpy.context.window_manager.popup_menu(draw, title = title, icon = icon)

def every_X_seconds_word():
    ShowMessageBox("Hello World", "Many Wow" ,"BLENDER")
    return 5.0
bpy.app.timers.register(every_X_seconds_word)


it make blender crash

import bpy 

def every_X_seconds_word():
    def ShowMessageBox(message = "", title = "Message Box", icon = 'INFO'): #Message function
        def draw(self, context):
            self.layout.label(text=message)
        bpy.context.window_manager.popup_menu(draw, title = title, icon = icon)
    ShowMessageBox("Hello World", "Many Wow" ,"BLENDER")
    return 5.0
bpy.app.timers.register(every_X_seconds_word)


i also tried within the app, also crash.

inside of this timer app there's also some operator that cannot work due to context issue ? for example i cannot do a screenshot every X seconds.

how can i bypass this?
this is how you get menu working in a app loop

import bpy
from bpy.types import Menu


class VIEW3D_MT_ScriptLauncher(Menu):
    bl_label = "Save Your File?"
    bl_idname = "OBJECT_MT_fc_main_menulaunchscript" #other id if two pies 

    def draw(self, context):
        layoutT = self.layout
        layoutT.label(text="30 minutes passed witouth any saves", icon='COLORSET_02_VEC')
        layoutT.label(text=" ")
        layoutT.separator()
        col = self.layout.column(align=False)
        col.label(text=" Quick save ")
        col.label(text=" Quick save as ")
        col.label(text=" Quick save as copy ")
        col.label(text=" Quick save as new version ")
        col.separator()
        col.label(text=" Don't ask anymore ")
        col.label(text=" No ")

    @staticmethod
    def every_n_sec(C_dict, times=10, interval=10):
        if times &gt; 0:
            bpy.ops.wm.call_menu(C_dict,
                name='OBJECT_MT_fc_main_menulaunchscript')

            bpy.app.timers.register(
                lambda: __class__.every_n_sec(C_dict, times - 1),
                first_interval=interval)


def register():
    bpy.utils.register_class(VIEW3D_MT_ScriptLauncher)

def unregister():
    bpy.utils.unregister_class(VIEW3D_MT_ScriptLauncher)



if __name__ == "__main__":
    register()

    # pass context dict to the function so bpy.ops works in timer
    C_dict = bpy.context.copy()


    bpy.app.timers.register(
        lambda: VIEW3D_MT_ScriptLauncher.every_n_sec(C_dict))