I am experimenting with creating a simple plugin to create a custom post type named project but am having some trouble with the rewrite rules not been flushed on activation.

I have the main plugin file with this function:

register_activation_hook( __FILE__, 'Project_Custom_Post_Type::activate' );

Then within my class I have this:

public function activate() {

My class has a construct of:

public function __construct() {
  add_action( 'init', array( $this, 'register_post_type' ), 0 );

I cannot see why it is not working? My deactivation flush works fine.

  • 'Project_Custom_Post_Type::activate' is not a valid callable type in PHP
    – Tom J Nowell
    Apr 20, 2021 at 11:42

4 Answers 4


Your string is not read as a callback. You should pass an array:

$pcpt = new Project_Custom_Post_Type;
register_activation_hook( __FILE__, array( $pcpt, 'activate' ) );

Note that init happens before plugin activation, so not callbacks from your class will be executed.


On activation, the "init" action has already run. So your flush is actually taking place just fine, but your post type is not being registered before the flush takes place. Add the code to register your post type to your activation function, before you flush the rewrite rules.

Also, yes, your activation hook call is incorrect, as toscho pointed out.

  • Ok so I now have it working with this: register_activation_hook( __FILE__, array( $project, 'activate' ) ); With my activate function including this line: $this->my_register_post_type(); All works great. I still have the my_register_post_type(); function being called on 'init' also. I presume it needs to be called in both places? Oct 14, 2013 at 20:03
  • Yes, it needs to be in both places.
    – Otto
    Oct 15, 2013 at 10:52

This might not be a direct answer to this question. However, I've seen multiple workarounds for dealing with this issue ( flush_rewrite_rules() being executed first ).

A workaround was to set a flag ( using add_option() ) and then hook to the init, and flush the rewrite rules if the flag exists. A bit nasty.

In case whatever you want to register can be registered after plugin activation, you can try a different approach.

register_activation_hook() internally registers an action hook on activate_PLUGIN_NAME. so what you can do, is to register your codes on the same hook with a higher precedence.

For example:

// __FILE__ is the main plugin file that contains the plugin headers.
$activation_hook = plugin_basename( __FILE__ );

// Register your stuff here, using a lower priority.
add_action( "activate_{$activation_hook}", "your_callback_to_register", 1, 1 );

Now, you can use register_activation_hook() freely, as it will run at a higher priority. Although pay attention, this hook might be too late to register certain stuff, but it works nicely for adding rewrite rules on plugin activation.


What we need to do on plugin activation is this instead:


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.