Magento 2.2.0 Invalid Document Element 'resource': The attribute 'title' is required but missing
To find the file with the missing attribute you can modify the following file
vendor/magento/framework/Config/Reader/Filesystem.php
add following code
foreach($configMerger->getDom()->getElementsByTagName('resource') as $element ){
if (!$element->hasAttribute('title')) {
var_dump($configMerger->getDom()->saveXML($element));
}
}
to the method
protected function _readFiles($fileList)
so it should look like
protected function _readFiles($fileList)
{
/** @var \Magento\Framework\Config\Dom $configMerger */
$configMerger = null;
foreach ($fileList as $key => $content) {
try {
if (!$configMerger) {
$configMerger = $this->_createConfigMerger($this->_domDocumentClass, $content);
} else {
$configMerger->merge($content);
}
} catch (\Magento\Framework\Config\Dom\ValidationException $e) {
throw new \Magento\Framework\Exception\LocalizedException(
new \Magento\Framework\Phrase("Invalid XML in file %1:\n%2", [$key, $e->getMessage()])
);
}
}
if ($this->validationState->isValidationRequired()) {
$errors = [];
if ($configMerger && !$configMerger->validate($this->_schemaFile, $errors)) {
foreach($configMerger->getDom()->getElementsByTagName('resource') as $element ){
if (!$element->hasAttribute('title')) {
var_dump($configMerger->getDom()->saveXML($element));
}
}
$message = "Invalid Document \n";
throw new \Magento\Framework\Exception\LocalizedException(
new \Magento\Framework\Phrase($message . implode("\n", $errors))
);
}
}
$output = [];
if ($configMerger) {
$output = $this->_converter->convert($configMerger->getDom());
}
return $output;
}
Now you will be able to see a dump of the wrong XML element.
My best guess is that you have a <resource>
-tag in any etc/acl.xml
-file with a missing title
-attribute. Usually this would throw the issue that you could not create or edit a new role. I'm guessing that they created an extra check in 2.2 to detect this more earlier.
Better check the acl.xml
-files of your own custom extensions and/or those of 3rd party extensions. Please note: the title
-attribute is only required for new <resource>
-nodes. So if your adding a new resource-node to an existing resource node (provided by another module) there is no need to add the title
-attribute to those. For example:
<!-- provided by Magento_Backend, so they already have a title: -->
<resource id="Magento_Backend::stores">
<resource id="Magento_Backend::stores_settings">
<!-- provided by Magento_Config: -->
<resource id="Magento_Config::config">
<!-- New resource! Title is required: -->
<resource id="Vendor_Module::config_general" title="Something" translate="title"/>
</resource>
</resource>
</resource>
I had this same problem recently. A couple of observations and a workaround.
1) It would help immensely if instead of 'Invalid Document' it told you which document was invalid.
2) The setup:upgrade process should probably do some pre-flight checks to make sure it can do the upgrade.
Anyway, if you're stuck trying to find a missing title in the dozens of acl.xml files, but need to get a site back online quick, the quick workaround is to make the title attribute optional instead of required.
Edit vendor/magento/framework/Acl/etc/acl_merged.xsd
Find the line
<xs:attribute name="title" type="typeTitle" use="required" />
replace with
<xs:attribute name="title" type="typeTitle" use="optional" />
re-run magento setup:upgrade
You'll still need to find the plugin with the missing title at some point.