Why does my add-on work from the 'Add' menu in the header but not from Shift+A? My modal addon is using raycast, I've taken a function from Blender python templates: everything worked fine. However when I try to add my addon to Add menu (VIEW3D_MT_add), it starts to act weird: I think that the issue is with contexts, but I don't know how to solve this. 

Here's a stripped down test code:

import bpy

bl_info = {
"name": "Test Addon", 
"category": "Object",
"version": (0, 0, 1),
"blender": (2, 80, 0),}

class OBJECT_OT_my_addon(bpy.types.Operator):
    bl_idname = "object.my_addon"
    bl_label = "My Addon Name"
    bl_options = {"REGISTER", "UNDO"}

    def invoke(self, context, event):
      print(context.region_data)
      return {'FINISHED'}

def menu_func(self, context):
    # self.layout.operator_context = 'INVOKE_DEFAULT'
    self.layout.operator("object.my_addon")

def register():
    bpy.utils.register_class(OBJECT_OT_my_addon)
    bpy.types.VIEW3D_MT_add.append(menu_func)

def unregister():
    bpy.utils.unregister_class(OBJECT_OT_my_addon)
    bpy.types.VIEW3D_MT_add.remove(menu_func)


context.region_data is needed for raycast, so this addon prints it out. 

When I run it from Viewport Add menu, it prints out RegionView3D: everything is fine. However if I run it from Shift+A Add menu, I'm getting an error: 

ERROR (wm.operator): c:\b\win64_cmake_vs2017\win64_cmake_vs2017\blender.git\source\blender\windowmanager\intern\wm_event_system.c:1486 wm_operator_invoke: invalid operator call 'OBJECT_OT_my_addon'

if I uncomment the self.layout.operator_context = 'INVOKE_DEFAULT' in menu_func, it starts working fine from the Shift+A menu and prints out RegionView3D, but! if I run it from Viewport Add menu it prints None and my raycast doesn't work.
The menu is in the header region

Put together this for prior version of this question. Can also get the region 3d view from space_data.region_3d or area.spaces.active.region_3d

When invoked from the header the region will be the header.

import bpy
from bpy_extras import view3d_utils
from mathutils import Vector

bl_info = {
"name": "Test Addon", 
"category": "Object",
"version": (0, 0, 1),
"blender": (2, 80, 0),}

def get_v(context, event):
    scene = context.scene
    area = context.area
    region = area.regions[-1] # or search for region.type == 'WINDOW'
    space = area.spaces.active
    rv3d = space.region_3d
    print(context.region.type, rv3d == context.region_data) # See Output
    coord = event.mouse_region_x, event.mouse_region_y

    print(region, rv3d, coord)

class OBJECT_OT_my_addon(bpy.types.Operator):
    bl_idname = "object.my_addon"
    bl_label = "My Addon Name"
    bl_options = {"REGISTER", "UNDO"}

    def invoke(self, context, event):
      print(get_v(context, event))
      return {'FINISHED'}

def menu_func(self, context):
    self.layout.operator_context = 'INVOKE_DEFAULT'
    self.layout.operator("object.my_addon")

def register():
    bpy.utils.register_class(OBJECT_OT_my_addon)
    bpy.types.VIEW3D_MT_add.append(menu_func)

def unregister():
    bpy.utils.unregister_class(OBJECT_OT_my_addon)
    bpy.types.VIEW3D_MT_add.remove(menu_func)

if __name__ == "__main__":
    register()


The See Output print above from header menu

HEADER False


and from shiftA menu

WINDOW True


To sum up, only use context.region_data if you are sure you are in the 3D view window. Python console code, a is a view3d area

&gt;&gt;&gt; a.type
'VIEW_3D'

&gt;&gt;&gt; for r in a.regions:
...     r.type
...     
'TOOL_HEADER'
'HEADER'
'TOOLS'
'UI'
'WINDOW'


Another method would be to use 'INVOKE_REGION_WIN' as the operator context, to make sure the 'WINDOW' region is used.