Several months ago, while working on a project for a client, I created a feature. Among other things, that feature defined a custom action (these appear under site settings). The only purpose for this custom action was to demonstrate to me that the feature activation was working as expected. Basically, I used it as a crude form of debugging.
Much to my embarrassment, this debugging artifact made its way from dev to UAT and to production before someone got around to asking, "what is this xyzzy link?"
By now, we’re in production and I really don’t want to uninstall the feature, fix elements.xml and then reinstall.
Todd Bleaker pointed out an easy way to handle it. In his words:
"CustomActions are not copied into the database, they are read directly from the Elements.xml file and copied into application state at runtime. So, you don’t need to deactivate, uninstall, reinstall, and reactivate the Feature to remove the CustomAction. Just remove it from the Elements.xml file and recycle the application pool(s) effected. The next time the Feature is in scope, you won’t see the CustomAction anymore."
I followed his instructions and, of course, they work.
In my case, this is a department level installation with just a single WFE. If you find yourself with this problem in future and with multiple WFE’s, I believe you’ll have to make the change in each.