XF 2.2 Cannot declare class ...because the name is already in use in src/XF/Extension.php at line 171

bzcomputers

Well-known member
I've got this error popping up on my Resource Manage pages after I recently updated an add-on...


The full error is: ErrorException: [E_WARNING] Cannot declare class Siropu\AdsManager\XFRM\Pub\Controller\XFCP_ResourceItem, because the name is already in use in src/XF/Extension.php at line 171.

Further looking into it the error and the XenForo file referenced src/XF/Extension.php at line 171. When going to that location, in extension.php, I do see notations in the XenForo file saying "// TODO: there may be a situation where this fails. If we've changed the extensions after classes have
// been loaded, it's possible these classes will already be loaded with a different config. Figure out
// how to handle that if possible. Remains to be seen if it comes up (mostly relating to add-on imports)."

I've had to completely disable my Resource Manager now (been over 2 weeks on a live site) since the error began occurring. Yes, I reported the issue to the add-on author and also opened a ticket with XenForo but at this point I haven't gotten any solutions or suggestions. Just putting this out there to get a few more eyes on it and see if someone else with a little more XenForo programming knowledge than me might be able to point me in the right direction to getting this fixed. Thanks.
 

bzcomputers

Well-known member
We're getting this error with multiple plugins now...
Was there ever a solution to this?
Yes. @Chris D found that when this error was showing up the add-on in question had duplicate class extensions. The duplicate extension tries to apply the same class a second time which is why you see the error.

The good thing is, it is a simple fix. You just delete the duplicate class extension(s) and rebuild the add-on. Do this by enabling "Development" mode and going to "Class Extensions" option and looking through the list. You should not see any duplicates of a class extension within the same add-on. If there is delete the duplicate(s) and then go to the add-on an select "rebuild".

class-extensons-1.jpg

class extensions-2.jpg class-extensons-3.jpg


The confusing part is he is not sure why it happened and sounded as if he may have not come across the issue before. This was just a couple days ago and now your're reporting the same issue so this issue may be becoming more prevalent.

The two add-ons that had duplicate extensions for me were:
Ads Manager 2
[cv6] NodeIcons

Not saying there is an issue with either add-on. It just might be a good idea for those of us that do come across this issue to keep track of the add-ons displaying this issue in case it is something that can be addressed from the add-on side itself. XenForo may also be able to implement a check for duplicate extensions if this becomes more wide spread.
 
Last edited:

VersoBit

Well-known member
I had several addons do this last night to me:
  • Redis Cache by Xon
  • Font Awesome Manager by Kirby
  • Multi Prefix by Xon
I was able to get Multi-Prefix and Font Awesome working by uninstalling and re-installing.

Redis cache however is still hobbled, so will have to try the above process to see if it resolves.
 

Xon

Well-known member
You should be able to disable the add-on, and then do a rebuild which should remove the duplicate entries. No idea how they got added but I suspect something isn't 100% right with the web installer.
 

bzcomputers

Well-known member
You should be able to disable the add-on, and then do a rebuild which should remove the duplicate entries. No idea how they got added but I suspect something isn't 100% right with the web installer.

I know this did not work for me for when I was initially trying to find the cause of the error. I disabled add-on and rebuilt multiple times, with no change. Error remained, and eventually when the duplicate entries were found to be the cause they of course were still there and must have been from the start.
 

bzcomputers

Well-known member
I'm very confused at how the add-on got into that state then!
I feel the same way. If it was a single add-on with a single duplicate class extension it probably wouldn't concern me. For me, it was 2 add-ons and a total of 4 duplicates - of which only one was currently giving me an error because the other duplicates related to add-on options I wasn't actively using.

Now another XenForo customer has reported similar issues in this thread with multiple add-ons in his setup causing errors now. At this point we are well beyond a fluke and who knows how many duplicate class extensions could be out there that just aren't causing issues right now.

The 2 add-ons I had with issues had both been installed on my setup for a couple years now. Over that time they have gone through multiple updates, along with XenForo with no issues showing until just recently (last couple months). This leads me to think statistically a recent XenForo update may be in play as the possible cause, rather than multiple add-ons that have been around for years all having the same issue popping up at the same time.

I'm sure it is on @Chris D 's radar. Hopefully @VersoBit reports back with his final findings.

If it comes down to it, adding a duplicate class extension check to XenForo should be pretty simple. Although, finding why it is happening should definitely be the end game.

Maybe if we could get some other admins to check their setups for duplicate extensions we could get a clearer picture of how prolific this issue is.
 

VersoBit

Well-known member
We ended up having to fully remove each affected addon, then reinstall them to get the functionality back from the addons... I did recently search through our database logs and I found the following in errors:

Code:
2022-07-04 13:50:24 6 [ERROR] InnoDB: Record in index `from_class` of table `<redacted>`.`xf_class_extension` was not found on update: TUPLE (info_bits=0, 3 fields): {[25]XF\Admin\Controller\Forum(0x58465C41646D696E5C436F6E74726F6C6C65725C466F72756D),[30]XFES\XF\Admin\Controller\Forum(0x584645535C58465C41646D696E5C436F6E74726F6C6C65725C466F72756D),[4]    (0x000003EB)} at: COMPACT RECORD(info_bits=0, 3 fields): {[50]XenConcept\ProjectManager\Service\ProjectTask\Edit(0x58656E436F6E636570745C50726F6A6563744D616E616765725C536572766963655C50726F6A6563745461736B5C45646974),[65]SV\MultiPrefix\XenConcept\ProjectManager\Service\ProjectTask\Edit(0x53565C4D756C74695072656669785C58656E436F6E636570745C50726F6A6563744D616E616765725C536572766963655C50726F6A6563745461736B5C45646974),[4]    (0x000003A9)}
2022-07-04 13:50:24 6 [ERROR] InnoDB: Record in index `from_class` of table `<redacted>`.`xf_class_extension` was not found on update: TUPLE (info_bits=0, 3 fields): {[15]XF\Entity\Forum(0x58465C456E746974795C466F72756D),[20]XFES\XF\Entity\Forum(0x584645535C58465C456E746974795C466F72756D),[4]    (0x000003EC)} at: COMPACT RECORD(info_bits=0, 3 fields): {[25]XF\Admin\Controller\Forum(0x58465C41646D696E5C436F6E74726F6C6C65725C466F72756D),[30]XFES\XF\Admin\Controller\Forum(0x584645535C58465C41646D696E5C436F6E74726F6C6C65725C466F72756D),[4]   P(0x00000450)}
2022-07-04 13:50:24 6 [ERROR] InnoDB: Record in index `from_class` of table `<redacted>`.`xf_class_extension` was not found on update: TUPLE (info_bits=0, 3 fields): {[14]XF\Entity\Post(0x58465C456E746974795C506F7374),[19]XFES\XF\Entity\Post(0x584645535C58465C456E746974795C506F7374),[4]    (0x000003ED)} at: COMPACT RECORD(info_bits=0, 3 fields): {[15]XF\Entity\Forum(0x58465C456E746974795C466F72756D),[20]XFES\XF\Entity\Forum(0x584645535C58465C456E746974795C466F72756D),[4]   Q(0x00000451)}
2022-07-04 13:50:24 6 [ERROR] InnoDB: Record in index `from_class` of table `<redacted>`.`xf_class_extension` was not found on update: TUPLE (info_bits=0, 3 fields): {[16]XF\Entity\Thread(0x58465C456E746974795C546872656164),[21]XFES\XF\Entity\Thread(0x584645535C58465C456E746974795C546872656164),[4]    (0x000003EE)} at: COMPACT RECORD(info_bits=0, 3 fields): {[14]XF\Entity\Post(0x58465C456E746974795C506F7374),[19]XFES\XF\Entity\Post(0x584645535C58465C456E746974795C506F7374),[4]   R(0x00000452)}
2022-07-04 13:50:24 6 [ERROR] InnoDB: Record in index `from_class` of table `<redacted>`.`xf_class_extension` was not found on update: TUPLE (info_bits=0, 3 fields): {[23]XF\Pub\Controller\Forum(0x58465C5075625C436F6E74726F6C6C65725C466F72756D),[28]XFES\XF\Pub\Controller\Forum(0x584645535C58465C5075625C436F6E74726F6C6C65725C466F72756D),[4]    (0x000003EF)} at: COMPACT RECORD(info_bits=0, 3 fields): {[16]XF\Entity\Thread(0x58465C456E746974795C546872656164),[21]XFES\XF\Entity\Thread(0x584645535C58465C456E746974795C546872656164),[4]   S(0x00000453)}
2022-07-04 13:50:24 6 [ERROR] InnoDB: Record in index `from_class` of table `<redacted>`.`xf_class_extension` was not found on update: TUPLE (info_bits=0, 3 fields): {[24]XF\Pub\Controller\Thread(0x58465C5075625C436F6E74726F6C6C65725C546872656164),[29]XFES\XF\Pub\Controller\Thread(0x584645535C58465C5075625C436F6E74726F6C6C65725C546872656164),[4]    (0x000003F0)} at: COMPACT RECORD(info_bits=0, 3 fields): {[23]XF\Pub\Controller\Forum(0x58465C5075625C436F6E74726F6C6C65725C466F72756D),[28]XFES\XF\Pub\Controller\Forum(0x584645535C58465C5075625C436F6E74726F6C6C65725C466F72756D),[4]   T(0x00000454)}
2022-07-04 13:50:24 6 [ERROR] InnoDB: Record in index `from_class` of table `<redacted>`.`xf_class_extension` was not found on update: TUPLE (info_bits=0, 3 fields): {[20]XF\Repository\Thread(0x58465C5265706F7369746F72795C546872656164),[25]XFES\XF\Repository\Thread(0x584645535C58465C5265706F7369746F72795C546872656164),[4]    (0x000003F1)} at: COMPACT RECORD(info_bits=0, 3 fields): {[24]XF\Pub\Controller\Thread(0x58465C5075625C436F6E74726F6C6C65725C546872656164),[29]XFES\XF\Pub\Controller\Thread(0x584645535C58465C5075625C436F6E74726F6C6C65725C546872656164),[4]   U(0x00000455)}
2022-07-04 13:50:24 6 [ERROR] InnoDB: Record in index `from_class` of table `<redacted>`.`xf_class_extension` was not found on update: TUPLE (info_bits=0, 3 fields): {[16]XF\Search\Search(0x58465C5365617263685C536561726368),[21]XFES\XF\Search\Search(0x584645535C58465C5365617263685C536561726368),[4]    (0x000003F2)} at: COMPACT RECORD(info_bits=0, 3 fields): {[20]XF\Repository\Thread(0x58465C5265706F7369746F72795C546872656164),[25]XFES\XF\Repository\Thread(0x584645535C58465C5265706F7369746F72795C546872656164),[4]   V(0x00000456)}

Not sure what's causing that, or how it could be resolved.
 

PaulB

Well-known member
Not sure what's causing that, or how it could be resolved.
Are you using MariaDB? If so, which version, and are you using any special arrangements (e.g., replication)? Have you done anything to your database server recently that could've caused corruption?

For anyone else running into this, are you using replication? What happens if you run the SQL query CHECK TABLE xf_class_extension; ?
 
Last edited:

Xon

Well-known member
MariaDB's parallel replication could definitely cause these observed errors, as the commits can be applied out of order on the replica. But I think any primary-replica setup could trigger this issue.

The fix requires at least 2 changes on the XenForo side:
  • Ensure any cache rebuild queries hit the primary SQL instance instead of replicas.
  • Wrap the add-on data updates in a transaction, as it is doing multi-entity updates with updates+deletes which must be consistent at any given time.
    • This includes the select statement to build the add-on data list to update, as this must end up on the same server as the updates!
 
Last edited:

VersoBit

Well-known member
Are you using MariaDB? If so, which version, and are you using any special arrangements (e.g., replication)? Have you done anything to your database server recently that could've caused corruption?

For anyone else running into this, are you using replication? What happens if you run the SQL query CHECK TABLE xf_class_extension; ?
MySQL version10.7.4 (10.7.4-MariaDB-log)
How we're configured:
  • 1x Master (Used as Write)
  • 2x Read (Used as Read, Load balanced by nginx incase one drops out, or needs a restart for updates)
We've been debating on a transition to Galera but have not made the move yet.

Our current setup involves the following procedures:
  • Updates Require:
    • Disable all read MySQL Slaves from config.php.
    • Continue with Updates/Upgrades.
    • Restore MySQL Slaves to config.php after upgrade is complete.
Furthering on this, even though we see these errors in our logs, we do not experience any issues with our install after we uninstalled and reinstalled the addons - Is there a set of queries you could recommend to clear this out if it is indeed corruption?

MariaDB's parallel replication could definitely cause these observed errors, as the commits can be applied out of order on the replica. But I think any primary-replica setup could trigger this issue.

The fix requires at least 2 changes on the XenForo side:
  • Ensure any cache rebuild queries hit the primary SQL instance instead of replicas.
  • Wrap the add-on data updates in a transaction, as it is doing multi-entity updates with updates+deletes which must be consistent at any given time.
    • This includes the select statement to build the add-on data list to update, as this must end up on the same server as the updates!
I agree with what Xon has stated here in regards to path to a solution; though I am still unsure of how our tables got this issue considering we disable our read slaves for any administration task.
 

PaulB

Well-known member
Looking over the code that handles importing add-on data from XML, I'm guessing the cause is replication. If XenForo reads the list of existing class extensions from the replica, it could end up inserting duplicates, especially if the installation is interrupted. Upgrades and installations tend to result in replication lag, so you're eventually goint to hit the race condition that arises in that code path.

You can avoid this by importing from JSON (_output) instead of XML (_data), but doing that safely in production requires a lot of care and custom code. The JSON importer uses a transaction, so it won't read from the replica.

I am still unsure of how our tables got this issue considering we disable our read slaves for any administration task.
Unless that's automated, humans are humans, and someone will eventually forget.
 

VersoBit

Well-known member
Looking over the code that handles importing add-on data from XML, I'm guessing the cause is replication. If XenForo reads the list of existing class extensions from the replica, it could end up inserting duplicates, especially if the installation is interrupted. Upgrades and installations tend to result in replication lag, so you're eventually goint to hit the race condition that arises in that code path.

You can avoid this by importing from JSON (_output) instead of XML (_data), but doing that safely in production requires a lot of care and custom code. The JSON importer uses a transaction, so it won't read from the replica.


Unless that's automated, humans are humans, and someone will eventually forget.
Was definitely disabled as I can verify it in the audit log (we track all file changes to core files); before I started the upgrade I am able to verify that my read slave's were down at the time of upgrade (disabled at the docker level, and master was set as the only database (config.php)).

I'd consider this one a fluke, but considering that there is a chance of human error - I argue that there should be a fix on XenForo's part to handle switchover's during upgrades; this could be as simple as forcing the database to use the write option for reading and writing during maintence; or alternatively a method to provide a different database configuration for the acp (just maybe some food for thought).
 

Xon

Well-known member
A quick workaround is adding this to after the database configuration parts of config.php
PHP:
$config['db']['adapterClass'] = \XF\Db\Mysqli\ReplicationAdapter::class;
if (\XF::app()->container('app.classType') !== 'Pub')
{
   $config['db']['adapterClass'] = \XF\Db\Mysqli\Adapter::class;
}
This way for the admincp & installer, it will disable using the replication adapter and only communicate with the primary SQL instance.
 
Last edited:

VersoBit

Well-known member
A quick workaround is adding this to after the database configuration parts of config.php
PHP:
$config['db']['adapterClass'] = \XF\Db\Mysqli\ReplicationAdapter::class;
if ($app->container('app.classType') !== 'Pub')
{
   $config['db']['adapterClass'] = \XF\Db\Mysqli\Adapter::class;
}
This way for the admincp & installer, it will disable using the replication adapter and only communicate with the primary SQL instance.
Cant seem to get this going, we get the following:
Code:
2022/07/05 02:18:11 [error] 1769780#1769780: *200613 FastCGI sent in stderr: "PHP message: PHP Fatal error:  Uncaught ErrorException: [E_WARNING] Undefined variable $app in /home/<redacted>/src/config.php:106
Stack trace:
#0 /home/fellowsfilm/src/config.php(106): XF::handlePhpError(2, '[E_WARNING] Und...', '/home/<redacted>...', 106)
#1 /home/fellowsfilm/src/XF/App.php(166): require('/home/<redacted>...')
#2 /home/fellowsfilm/src/XF/Container.php(31): XF\App->XF\{closure}(Object(XF\Container))
#3 /home/fellowsfilm/src/XF/App.php(1572): XF\Container->offsetGet('config')
#4 /home/fellowsfilm/src/XF/Container.php(31): XF\App->XF\{closure}(Object(XF\Container))
#5 /home/fellowsfilm/src/XF/App.php(2840): XF\Container->offsetGet('extension')
#6 /home/fellowsfilm/src/XF/App.php(2868): XF\App->extension()
#7 /home/fellowsfilm/src/XF/App.php(369): XF\App->extendClass('XF\\InputFiltere...')
#8 /home/fellowsfilm/src/XF/Container.php(31): XF\App->XF\{closure}(Object(XF\Container))
#9 /home/fellowsfilm/src/XF/App.php(231): XF\Container->offsetGet('inputFilterer')
 

bzcomputers

Well-known member
Running MariaDB 10.6.8 also but without replication.

I did run a check on the class_extention table and it was corrupt. The error specifically mentioned both of the add-ons which previously had duplicate class extensions.

Code:
907202 [ERROR] InnoDB: index records in a wrong order in `from_class` of table `XXX_`.`xf_class_extension`: TUPLE (info_bits=0, 3 fields): {[32]XFRM\Pub\Controller\ResourceItem(0x5846524D5C5075625C436F6E74726F6C6C65725C5265736F757263654974656D),[50]Siropu\AdsManager\XFRM\Pub\Controller\ResourceItem(0x5369726F70755C4164734D616E616765725C5846524D5C5075625C436F6E74726F6C6C65725C5265736F757263654974656D),[4]    (0x00000010)}, COMPACT RECORD(info_bits=0, 3 fields): {[25]XF\Admin\Controller\Asset(0x58465C41646D696E5C436F6E74726F6C6C65725C4173736574),[38]cv6\NodeIcon\XF\Admin\Controller\Asset(0x6376365C4E6F646549636F6E5C58465C41646D696E5C436F6E74726F6C6C65725C4173736574),[4]   B(0x00000042)}
 

Xon

Well-known member
Cant seem to get this going, we get the following:
Code:
2022/07/05 02:18:11 [error] 1769780#1769780: *200613 FastCGI sent in stderr: "PHP message: PHP Fatal error:  Uncaught ErrorException: [E_WARNING] Undefined variable $app in /home/<redacted>/src/config.php:106
Stack trace:
#0 /home/fellowsfilm/src/config.php(106): XF::handlePhpError(2, '[E_WARNING] Und...', '/home/<redacted>...', 106)
#1 /home/fellowsfilm/src/XF/App.php(166): require('/home/<redacted>...')
#2 /home/fellowsfilm/src/XF/Container.php(31): XF\App->XF\{closure}(Object(XF\Container))
#3 /home/fellowsfilm/src/XF/App.php(1572): XF\Container->offsetGet('config')
#4 /home/fellowsfilm/src/XF/Container.php(31): XF\App->XF\{closure}(Object(XF\Container))
#5 /home/fellowsfilm/src/XF/App.php(2840): XF\Container->offsetGet('extension')
#6 /home/fellowsfilm/src/XF/App.php(2868): XF\App->extension()
#7 /home/fellowsfilm/src/XF/App.php(369): XF\App->extendClass('XF\\InputFiltere...')
#8 /home/fellowsfilm/src/XF/Container.php(31): XF\App->XF\{closure}(Object(XF\Container))
#9 /home/fellowsfilm/src/XF/App.php(231): XF\Container->offsetGet('inputFilterer')
Change the line:
PHP:
if ($app->container('app.classType') !== 'Pub')
to
PHP:
if (\XF::app()->container('app.classType') !== 'Pub')
 
Top