I am using wp_insert_post and all the fields are working except tax_input is working. Is there something wrong with my code?

$customtax =  array(
'product_link' => $link,
'product_price' => $price,
'product_description' => $desc );
$my_post = array(
  'post_title'    => $title,
  'post_content'  => $content,
  'post_type'     => 'products',
  'tax_input' => $customtax

Thank you in advance

6 Answers 6


The most common reason is that you run this code without user context (cron, etc). Within wp_insert_post() context WP will check if user has permissions to a taxonomy. No user equals no permissions equals no terms being assigned.

The workaround is to create post first, then assign terms to it. When terms are assigned explicitly via API method (such as wp_set_object_terms()) the permissions check is not performed.

  • So the workaround is to the wp_insert_post() without the tax_input and then once that's completed, use wp_set_object_terms()? But what if that's not possible? For example, a plugin that let's you filter the args for wp_insert_post() but has no hook for once that's completed. This answer might work but it feels far from ideal. There's something quirky about wp_insert_post() and 'tax_input'. Certainly, there's a true clean slate solution. Dec 28, 2016 at 16:13

It turns out that tax_input does not work if a user does not have the capabilities to work with a custom taxonomy:

wp-includes/post.php (wp_insert_post): enter image description here

So either add the correct caps or use wp_set_object_terms()


As you said in comment that plugin will do the filters and don't have hook, I think plugin must have wp_insert_post hook anyway. Otherwise how do you insert the post ? I am answering this after so long time cause I faced the same issue and found the only one way.

$new_id = wp_insert_post($post_arr, true);
$status = wp_set_object_terms($new_id, $term_id, 'location');

here location is the term slug. Someday someone will get this helpful..


When using tax_input for post insertion, be sure to use term taxonomy id, since slugs or names seem to be thrown away

$my_post = array(
'post_title'    => $title,
'post_content'  => $content,
'post_type'     => 'products',
'tax_input' => array('myTax', array(4,458,11478)),

The question is old, still I spent quite some time to figure out that insert post (wp_insert_post) show this behaviour when used inside the cron action.

Insert post and then wp_set_object_terms is a good workaround, however, setting the current user before inserting post also worked for me

$user_id = 1;
$user = get_user_by( 'id', $user_id );
wp_set_current_user( $user_id, $user->user_login);

$new_id = wp_insert_post($my_post);

As @Rarst said WordPress checks during the wp_insert_post() if a current user has permission to add taxonomy terms. You also see from the post.php Line:3352

    if ( current_user_can( $taxonomy_obj->cap->assign_terms ) ) {
        wp_set_post_terms( $post_ID, $tags, $taxonomy );

If you are running the wp_insert_post code without having a logged in user you can set a current user by using the wp_set_current_user() method.

    $user = get_user_by('ID', $user_id);

    if( $user ){

         wp_set_current_user( $user_id, $user->user_login );


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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