Make WordPress Core

Opened 6 years ago

Closed 2 years ago

Last modified 2 years ago

#46297 closed defect (bug) (wontfix)

Unable to edit specific terms : rest_cannot_assign_term OR 403

Reported by: enps5's profile enps5 Owned by:
Milestone: Priority: normal
Severity: normal Version: 4.1
Component: Taxonomy Keywords:
Focuses: multisite, rest-api Cc:

Description (last modified by SergeyBiryukov)

This bug seems to be related to this changeset : [30056]

When i try create a new post with gutenberg and categorize the post taxonomy "bibliografía" i've this error :

Updating failed

The request body is :

{"status":"draft","title":"test","excerpt":"","categories":[4092],"content":"<!-- wp:paragraph -->\n<p>test</p>\n<!-- /wp:paragraph -->","id":1552}

Response from wordpress :

{"code":"rest_cannot_assign_term","message":"Sorry, you are not allowed to assign the provided terms.","data":{"status":403}}

On a WordPress network, when i attempt to edit the category as a wordpress super-user (this time i use the term.php's file) :
https://DOMAIN.TLD/wp-admin/term.php?taxonomy=category&tag_ID=4092&post_type=post&wp_http_referer=%2Fwp-admin%2Fedit-tags.php%3Ftaxonomy%3Dcategory%26post_type%3Dpost%26s%3Dbibliograf%25C3%25ADa
Wordpress return :

You need a higher level of permission.

Sorry, you are not allowed to edit this item.

A further look inside MySQL shows :

SELECT * FROM wp_2635_terms where term_id = 4092 ; 
+---------+---------------+--------------+------------+
| term_id | name          | slug         | term_group |
+---------+---------------+--------------+------------+
|    4092 | bibliografía  | bibliografia |          0 |
+---------+---------------+--------------+------------+

SELECT * FROM wp_2635_term_taxonomy where term_id = 4092 ; 
+------------------+---------+----------+-------------+--------+-------+
| term_taxonomy_id | term_id | taxonomy | description | parent | count |
+------------------+---------+----------+-------------+--------+-------+
|              254 |    4092 | category |             |      0 |     1 |
|              197 |    4092 | post_tag |             |      0 |     1 |
+------------------+---------+----------+-------------+--------+-------+

SELECT * FROM wp_2635_term_taxonomy GROUP BY term_id HAVING COUNT(term_id) > 1;
+------------------+---------+----------+-------------+--------+-------+
| term_taxonomy_id | term_id | taxonomy | description | parent | count |
+------------------+---------+----------+-------------+--------+-------+
|              254 |    4092 | category |             |      0 |     1 |
|              205 |    4191 | category |             |      0 |     7 |
|              357 |   52788 | category |             |      0 |     1 |
|              196 |   57611 | category |             |      0 |     4 |
|              354 |  226144 | category |             |      0 |     6 |
|              355 |  955714 | category |             |      0 |     2 |
|              298 | 1595453 | category |             |      0 |     2 |
|              313 | 1595513 | category |             |      0 |     8 |
|              177 | 1595576 | category |             |      0 |    12 |
|              379 | 1939409 | category |             |      0 |     6 |
|              329 | 1939420 | category |             |      0 |     4 |
|              312 | 1939471 | category |             |      0 |     2 |
|              314 | 1939479 | category |             |      0 |     4 |
|              359 | 2399420 | category |             |      0 |     1 |
|              438 | 2454276 | category |             |      0 |     1 |
+------------------+---------+----------+-------------+--------+-------+
15 rows in set (0.00 sec)

select term_id,slug,COUNT(slug) from wp_2635_terms group by slug having count(slug) > 1; 
+---------+------------------------------+-------------+
| term_id | slug                         | COUNT(slug) |
+---------+------------------------------+-------------+
|    4191 | antropologia                 |           4 |
| 1595576 | antropologia-linguistica     |           2 |
| 1595401 | audios                       |           3 |
|    4092 | bibliografia                 |           2 |
|  809963 | canal-uned                   |           3 |
|   52788 | cervantes                    |           2 |
| 2454276 | coelei                       |           2 |
| 1595453 | curso-de-verano              |           2 |
| 1939479 | edicion-de-textos            |           2 |
| 1595578 | etnografia-del-habla         |           3 |
| 1595478 | etnolinguistica              |           3 |
| 1939420 | eugenio-de-salazar           |           2 |
| 1939409 | glosonimia                   |           2 |
|  465167 | jornadas                     |           3 |
| 1595513 | lexicografia                 |           2 |
| 1595414 | metodologia-docente          |           3 |
| 1595416 | nuevas-propuestas-didacticas |           3 |
| 1595417 | paper-li                     |           3 |
|  200504 | proyectos                    |           3 |
|   57611 | publicaciones                |           2 |
| 2399420 | tecnolecto-marinero          |           2 |
|  226144 | uned                         |           2 |
| 1939471 | universidad-del-pacifico     |           2 |
|  955714 | vocabulario                  |           2 |
+---------+------------------------------+-------------+

desc wp_2635_terms ; 
+------------+---------------------+------+-----+---------+----------------+
| Field      | Type                | Null | Key | Default | Extra          |
+------------+---------------------+------+-----+---------+----------------+
| term_id    | bigint(20) unsigned | NO   | PRI | NULL    | auto_increment |
| name       | varchar(200)        | NO   | MUL |         |                |
| slug       | varchar(200)        | NO   | MUL |         |                |
| term_group | bigint(10)          | NO   |     | 0       |                |
+------------+---------------------+------+-----+---------+----------------+
4 rows in set (0.01 sec)

desc wp_2635_term_taxonomy ; 
+------------------+---------------------+------+-----+---------+----------------+
| Field            | Type                | Null | Key | Default | Extra          |
+------------------+---------------------+------+-----+---------+----------------+
| term_taxonomy_id | bigint(20) unsigned | NO   | PRI | NULL    | auto_increment |
| term_id          | bigint(20) unsigned | NO   | MUL | 0       |                |
| taxonomy         | varchar(32)         | NO   | MUL |         |                |
| description      | longtext            | NO   |     | NULL    |                |
| parent           | bigint(20) unsigned | NO   |     | 0       |                |
| count            | bigint(20)          | NO   |     | 0       |                |
+------------------+---------------------+------+-----+---------+----------------+

show create table  wp_2635_terms \G
*************************** 1. row ***************************
       Table: wp_2635_terms
Create Table: CREATE TABLE `wp_2635_terms` (
  `term_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(200) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '',
  `slug` varchar(200) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '',
  `term_group` bigint(10) NOT NULL DEFAULT '0',
  PRIMARY KEY (`term_id`),
  KEY `slug` (`slug`(191)),
  KEY `name` (`name`(191))
) ENGINE=InnoDB AUTO_INCREMENT=2454306 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
1 row in set (0.00 sec)


show create table  wp_2635_term_taxonomy \G
*************************** 1. row ***************************
       Table: wp_2635_term_taxonomy
Create Table: CREATE TABLE `wp_2635_term_taxonomy` (
  `term_taxonomy_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `term_id` bigint(20) unsigned NOT NULL DEFAULT '0',
  `taxonomy` varchar(32) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '',
  `description` longtext COLLATE utf8mb4_unicode_ci NOT NULL,
  `parent` bigint(20) unsigned NOT NULL DEFAULT '0',
  `count` bigint(20) NOT NULL DEFAULT '0',
  PRIMARY KEY (`term_taxonomy_id`),
  UNIQUE KEY `term_id_taxonomy` (`term_id`,`taxonomy`),
  KEY `taxonomy` (`taxonomy`)
) ENGINE=InnoDB AUTO_INCREMENT=462 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
1 row in set (0.00 sec)

If i delete (via MySQL delete statement) the post_tag with the term_id 4092, i can edit again the category. I had trouble reproducing the bug or to simply to identify the cause of the problem.

We're running a WordPress Network with ~5000blogs, i've identified this problem on 1300 sites.
We work with MySQL "classic replication" (master / slave), we already had a master x3 configuration with Galera Cluster. This can be an interesting element.

I remain available for aby further information.

Change History (22)

#1 @pento
6 years ago

  • Version changed from trunk to 4.1

#2 @digitwebtools
5 years ago

Hi Enps5,

Actually, we are experiencing something similar.

Our environment:

  • Wordpress Multisite 5.1.1 (we've been using it and upgrading it for years and years)
  • Table sitecategories defined
  • In table sitemeta, global_terms_enabled is set to 1

Steps to reproduce:

  • Create a new category "My category" THEN
  • Create a new tag "My tag" THEN
  • Create a new category with the same name of an existing tag, let's say "My tag" THEN
  • Create a new tag with the same name of an existing category, let's say "My category"

Now it will break if you do the following:

  • Edit the category "My tag" with the name of an existing tag, you'll get "You need a higher level of permission. Sorry, you are not allowed to edit this item."
  • Edit the tag "My category" with the name of an existing category, you'll get "You need a higher level of permission. Sorry, you are not allowed to edit this item."
  • Create / edit a content and assign the category "My tag" (with the name of an existing tag) or assign the tag "My category" (with the name of an existing category) and you'll get a 403 error with the response
    {"code":"rest_cannot_assign_term","message":"Sorry, you are not allowed to assign the provided terms.","data":{"status":403}}
    

Ticket created: https://core.trac.wordpress.org/ticket/47535

Best regards.

Alexandre - DIGIT WEBTOOLS

Last edited 5 years ago by digitwebtools (previous) (diff)

#3 @enps5
5 years ago

I made a script that allows to detect and delete duplicate taxonomies.
We choose to delete the post_tag but you can adapt the behavior.
I think this script can help some people who follow the ticket to identify taxonomies in their databases, the script produces a csv file like.

#!/bin/bash
for site in $(wp site list --field=url) ; do 
 for tagID in $(wp --allow-root term list category post_tag link_category post_format --format=csv --fields=term_id --url=${site}|sort -h |uniq -di); do
   mail=$(wp --allow-root user list --role=administrator --url=${site} --field=user_email --format=csv | tr "\n" ",")
   echo "Url; ${site} | tagID; ${tagID} | mail; ${mail}"
   echo "tagID:${tagID}"
   echo "Maybe should we execute: \"wp --allow-root term delete post_tag ${tagID} --url=${site}\""
 done
done

#4 @boonebgorges
5 years ago

@enps5 - it's been reported elsewhere by @digitwebtools that this issue may be linked to the use of global terms. Can you confirm whether you're using global terms on your network? Do you have a wp_sitecategories table with items in it?

Based on the results of your SQL queries, some sites on your network contain "shared terms", which are terms in multiple taxonomies that share the same term ID. In WordPress 4.1, we stopped created shared terms, and subsequent releases we introduced some tools that should have triggered the "splitting" of these shared terms - the creation of a new entry in wp_terms where previously a single entry was shared between multiple term_taxonomy_ids. See https://developer.wordpress.org/plugins/taxonomies/split-terms-wp-4-2/ for some background.

It appears that the split routines have not run on your installation. As a result, my hunch is that when you try to edit a term (an edit that happens via term_id), WordPress has insufficient information to decide which taxonomy you're referring to, and so it bails.

Your best bet is to ensure that there are no more shared terms on your installation. Ensure that each site on your network has an up-to-date database schema. Then, run a script that re-saves each shared term (WP will handle the term-splitting logic) or use a plugin like https://github.com/jjeaton/wp-find-shared-terms, which contains a CLI command that could be easily scripted for a multisite network.

#5 @enps5
5 years ago

Thank you for your help @boonebgorges, this has helped us to identify the origin of the problem, to allow it to never happen again and to act retroactively on old taxonomies.

As you suggested, there is a table wp_sitecategories and the option is enabled in wp_sitemeta :

desc wp_sitecategories;
+-------------------+--------------+------+-----+-------------------+-----------------------------+
| Field             | Type         | Null | Key | Default           | Extra                       |
+-------------------+--------------+------+-----+-------------------+-----------------------------+
| cat_ID            | bigint(20)   | NO   | PRI | NULL              | auto_increment              |
| cat_name          | varchar(55)  | NO   |     |                   |                             |
| category_nicename | varchar(200) | NO   | MUL |                   |                             |
| last_updated      | timestamp    | NO   | MUL | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
+-------------------+--------------+------+-----+-------------------+---------------------------

select count(*) from wp_sitecategories\G
*************************** 1. row ***************************
count(*): 267607
1 row in set (0.00 sec)

select * from wp_sitemeta where meta_key = 'global_terms_enabled' \G
*************************** 1. row ***************************
   meta_id: 28769
   site_id: 1
  meta_key: global_terms_enabled
meta_value: 0
1 row in set (0.00 sec)


After disabling the global_terms_enabled option it is no longer possible to reproduce the shared/duplicate terms bug (procedure to reproduce is described in the ticket https://core.trac.wordpress.org/ticket/47535)

To retroactively process old taxonomies, we ran this small script, which uses wp-cli and https://github.com/jjeaton/wp-find-shared-terms :

# Create a list with all blogs 
wp site list --field=url > /tmp/list_sites.txt 
# Check the list created
for site in $(cat /tmp/list_sites.txt) ; do
        echo "$site :" && wp --allow-root --path=/localdata/www/hypotheses shared-terms split --url=$site --verbose
done

bash $SCRIPT |& tee -a split_terms.log 
# We found 1095 shared taxonomies
grep -c -P "^\d" /root/detect_shared_terms.log
1095

Maybe we should have checked that the table wp_sitecategories did not contain any term_id = 0, we had the case on 3 blogs out of 315 where there was a split and on 5071 blogs in total. The term_id has 0 has been split in the wp_terms table of the corresponding blogs and this has broken the display, we could restore it by deleting the category to 0 in base.

About the "split_routines", I think there were several factors, i see this bug: https://core.trac.wordpress.org/ticket/33423
maybe in addition to this bug, we did not execute the upgrade_db correctly in 4.3 & 4.3.1 and so upgrade_420 and upgrade_430 could not launch split_all_shared_terms routines.

Everything seems resolved and in an efficient way, so thank you for your help, we remain available if you want more information about our case. Thanks!

#6 @boonebgorges
5 years ago

Thanks, @enps5. It sounds like this is the same issue as #47535. I'll close that one as a duplicate, and leave this one open for investigation.

#7 @boonebgorges
5 years ago

#47535 was marked as a duplicate.

#8 @Fraktjakt
5 years ago

Noticed too late that one of my sites never split its terms after updating, which has been the reason for strange behaviour all these years since the 4.2 update. And your suggested plugin WP_Find_shared_terms fails at splitting the terms as well.

Splitting post_tag "zzz"

ERROR: Term Taxonomy ID yyy could not be split!

etc, etc...

It seems as though both post_tags, categories, event-tag and nav_menu shares the same ID when they have used the same string. Is that why the split command isn't working? When event-tag and nav_menu items are involved? Or is it a server setting?
Any idea on how to solve it?

Last edited 5 years ago by Fraktjakt (previous) (diff)

#9 @Fraktjakt
5 years ago

Can not get much more info than the reply

code: "rest_cannot_assign_term"

When trying to publish/update a post with a conflicting category term.

And the Shared term plugin only outputs this

Splitting all shared terms
ERROR: Term Taxonomy ID 3 could not be split!
ERROR: Term Taxonomy ID 101 could not be split!
ERROR: Term Taxonomy ID 37 could not be split!
ERROR: Term Taxonomy ID 211 could not be split!
ERROR: Term Taxonomy ID 47 could not be split!
ERROR: Term Taxonomy ID 554 could not be split!
ERROR: Term Taxonomy ID 556 could not be split!
ERROR: Term Taxonomy ID 58 could not be split!
ERROR: Term Taxonomy ID 61 could not be split!
ERROR: Term Taxonomy ID 1870 could not be split!
ERROR: Term Taxonomy ID 547 could not be split!
ERROR: Term Taxonomy ID 71 could not be split!
ERROR: Term Taxonomy ID 1868 could not be split!
ERROR: Term Taxonomy ID 82 could not be split!
ERROR: Term Taxonomy ID 549 could not be split!
ERROR: Term Taxonomy ID 91 could not be split!
ERROR: Term Taxonomy ID 555 could not be split!
ERROR: Term Taxonomy ID 102 could not be split!
ERROR: Term Taxonomy ID 540 could not be split!
ERROR: Term Taxonomy ID 136 could not be split!
ERROR: Term Taxonomy ID 175 could not be split!
ERROR: Term Taxonomy ID 171 could not be split!
ERROR: Term Taxonomy ID 841 could not be split!
ERROR: Term Taxonomy ID 199 could not be split!
ERROR: Term Taxonomy ID 583 could not be split!
ERROR: Term Taxonomy ID 232 could not be split!
ERROR: Term Taxonomy ID 564 could not be split!
ERROR: Term Taxonomy ID 1880 could not be split!
ERROR: Term Taxonomy ID 287 could not be split!
ERROR: Term Taxonomy ID 1881 could not be split!
ERROR: Term Taxonomy ID 289 could not be split!
ERROR: Term Taxonomy ID 551 could not be split!
ERROR: Term Taxonomy ID 379 could not be split!
ERROR: Term Taxonomy ID 558 could not be split!
ERROR: Term Taxonomy ID 497 could not be split!
ERROR: Term Taxonomy ID 541 could not be split!
ERROR: Term Taxonomy ID 590 could not be split!
ERROR: Term Taxonomy ID 546 could not be split!
ERROR: Term Taxonomy ID 1558 could not be split!
ERROR: Term Taxonomy ID 565 could not be split!
ERROR: Term Taxonomy ID 1789 could not be split!
ERROR: Term Taxonomy ID 569 could not be split!
ERROR: Term Taxonomy ID 899 could not be split!
ERROR: Term Taxonomy ID 824 could not be split!
ERROR: Term Taxonomy ID 828 could not be split!
ERROR: Term Taxonomy ID 883 could not be split!
ERROR: Term Taxonomy ID 903 could not be split!
Process complete!
Processed: 47
Split: 0
Skipped: 0
Errors: 47

I have already tried removing all conflicting tags from posts and then manually deleting the tag taxonomy term in the database, but that didn't help at all.

It still says that I'm not even authorized (despite being admin) to even edit the conflicting categories while in backend.

Last edited 5 years ago by Fraktjakt (previous) (diff)

#10 @webtechIMT
4 years ago

Hello,

I've the same problem, I used the plugin wp-find-shared-terms (https://github.com/jjeaton/wp-find-shared-terms) and click "Split shared items" button, but it splits none :

Splitting all shared terms
Process complete!
Processed: 42
Split: 0
Skipped: 42
Errors: 0

And the bug remains when I want to edit a category (I have the error message "You need a higher level of permission. Sorry, you are not allowed to edit this item.")...

Is there any fix ?

Best regards,
Olivier.

#11 @webtechIMT
4 years ago

Hello,

Someone to answer or do I need to open a new ticket ?
I'm using WordPress 5.6

Best regards,
Olivier.

Update: I'm using WordPress multi-sites and in one of the 300 sites when I want to edit a category or a tag, I get error message "You need a higher level of permission. Sorry, you are not allowed to edit this item."

Last edited 4 years ago by sabernhardt (previous) (diff)

#12 @sabernhardt
4 years ago

#52423 was marked as a duplicate.

#13 @sabernhardt
4 years ago

  • Focuses multisite added

This ticket was mentioned in Slack in #core-multisite by sabernhardt. View the logs.


4 years ago

#15 @TimothyBlynJacobs
4 years ago

  • Focuses rest-api added

#16 @webtechIMT
4 years ago

Hello,

I've tried to copy my website (from a multi-sites install) to a fresh new WordPress 5.7 single site and the bug remains...

How can I fix it ?

Thanks
Oli

Last edited 4 years ago by webtechIMT (previous) (diff)

#17 @webtechIMT
3 years ago

  • Severity changed from normal to major

Hello,

I'm trying to edit a category and at line 39 of wp-admin/term.php : the function current_user_can( 'edit_term', $tag->term_id ) returns false.

I'm yet logged with administrator capabilities (as I can see in the database in wp_usermeta, key wp_capabilities and value : a:3:{s:13:"administrator";b:1;s:19:"manage_translations";b:1;s:9:"translate";b:1;})...

Could you help me please ?

PS : WP version is the latest : 5.9.1

Thank you,
Olivier.

#18 @SergeyBiryukov
3 years ago

  • Description modified (diff)

#19 @desrosj
2 years ago

  • Keywords close added

I'm going to mark this as a candidate to be closed, pending the discussion over on #21734 (see my latest comment ticket:21734#comment:19) which would result in the remaining related code being deprecated.

Global terms was "soft" deprecated in WP 3.0 12+ years ago, and is very broken in modern WordPress term meta does not work at all in addition to this report detailing problems with term splitting). I'd advise finding an alternative way to accomplish related needs.

#20 @TimothyBlynJacobs
2 years ago

  • Severity changed from major to normal

I agree @desrosj.

@webtechIMT Your issue does not look related to this. If it is only happening on one of your sites in the network, it sounds like you probably have custom code or a plugin that is modifying capability checks for terms on that site.

I'd recommend posting in the forums.

#21 @desrosj
2 years ago

  • Keywords close removed
  • Milestone Awaiting Review deleted
  • Resolution set to wontfix
  • Status changed from new to closed

Global terms is officially deprecated and no-opped in [54240]. Closing this as wontfix.

#22 @sabernhardt
2 years ago

#52423 was marked as a duplicate.

Note: See TracTickets for help on using tickets.