Technote

Development workflow Practical

Series Using hooks and filters properly Part 6 of 8

Removing someone else’s hook: name, priority and timing must match

remove_action says nothing when it fails, and a wrong name, a wrong priority and running too early all look identical. Checking the return value is half the fix.

When somebody else’s code conflicts with yours, removing it is often more honest than painting over it with a filter. Being able to suppress one specific output of a parent theme without editing that theme is a real benefit of the hook design.

The snag is that remove_action() and remove_filter() throw nothing when they fail. They return false and carry on, which means “did not remove” is indistinguishable from “was never there”.

Three things must match exactly

When removal works, and how it fails — the bottom three all return false in silence

Priority is what slips most often. When both sides use the default of 10 it simply works, so people stop passing it at all — and then a callback registered at 20 never comes off with a removal at 10. Check the number.

Timing is the next most common. You cannot remove something not yet registered. If the other side registers on init, your removal has to run at a later priority within init, or on wp_loaded.

add_action( 'after_setup_theme', function () {
	$ok = remove_action( 'kalium_wrapper_start', 'kalium_page_heading_title_display', 20 );

	// A false here means the name, the priority or the timing is wrong.
	// Do not let the failure pass silently.
} );

The identifier depends on what you are removing

A plain function is its name as a string. A static method is [ 'Some_Class', 'method' ] or 'Some_Class::method'.

An instance method needs the same object. If you cannot get hold of the instance used at registration, you cannot remove it. A singleton with an accessor is fine; a class that registers itself in its constructor and keeps no public reference leaves you no way in.

Closures cannot be removed by name, because there is no handle to name. That is a consequence of the design rather than a defect, and it produces a rule for the author of a plugin: do not attach closures to hooks other people may reasonably need to adjust. Use a named function, or a method on an instance you expose. Keep closures for internal wiring nobody has any reason to touch.

The trap of registration happening inside a hook

You also have to notice which hook the registration happens inside. This repository hit that while stripping the parent theme’s front-end scripts: they were enqueued from within wp_footer, so trying to dequeue them at wp_head found nothing in the queue yet.

The fix was not to dequeue the script but to remove the action that enqueues it. Stepping back one level and asking “what exactly am I removing?” is the answer in cases like this.

Afterwards, check what else disappeared. The same callback may have been doing something you did not know about. How we verify that during real work is published step by step on our process page, with related writing in the development workflow archive.

Next part

So far this has been about consuming extension points other people left. The next part turns it around — leaving hooks in your own code so that others can change behaviour without editing your files.

More on this topic

All technotes

Development workflow Advanced

The design QA checklist to run before release

Most design problems found after release are catchable before it, in order. Here is the pass, in three stages: rules, states and real devices.

Designers 6 min read

Development workflow Advanced

Never deploy without a way back

A rollback is not one button. It is two tracks — code and database — with an order to reverse them in, written down before you deploy.

Designers 9 min read

Development workflow Advanced

Adding your own hooks: extension points instead of edits

Code with no extension points gets forked or edited in place. Where you put do_action and apply_filters — and how many — decides how long that code survives.

Developers 7 min read

₩270,000 · Join the program