As part of our code cleanup exercise we have discovered that there were menu items pointing to objects which no longer exists in our environments, ie. legacy reports which were upgraded to SSRS but their menu items were never removed.

The following job could be used to identify such missing objects for any of your menu items. I would also recommend to double-check the xRef references to find connected objects, like security privileges/roles, to completely remove whatever you do not need.

static void WIK_findMissingMenuItems(Args _args)
    SysModelElement     element;
    SysModelElementData data;
    TreeNode            node;
    TreeNodePath        path;
    UtilElementType     type;
    while select element
        order by ElementType
        where (element.ElementType == UtilElementType::DisplayTool
            || element.ElementType == UtilElementType::OutputTool
            || element.ElementType == UtilElementType::ActionTool)
        exists join data
            where  data.Layer           >= UtilEntryLevel::isv
                && data.ModelElement    == element.RecId
        node = TreeNode::findNode(SysTreeNode::modelElement2Path(element));
        switch (str2enum(type, node.AOTgetProperty(#PropertyObjectType)))
            case UtilElementType::SSRSReport :
                path = #SSRSReportsPath;
            case UtilElementType::Report :
                path = #ReportsPath;
            case UtilElementType::Class :
                path = #ClassesPath;
            case UtilElementType::Form :
                path = #FormsPath;
            case UtilElementType::InfoPart :
                path = #InfoPartsPath;
            default :
                path = '';
        path = path + #AOTDelimiter + node.AOTgetProperty(#PropertyObject);
        if (!TreeNode::findNode(path))
            warning(strFmt('%1 - missing for %2', path, node.treeNodePath()));