- 🇺🇸United States fskreuz
I'm able to reproduce the issue on Drupal 10.3.1:
1. Install Drupal
2. Enable Languages and Content Translation modules
3. Add a language besides the default language (e.g default: English, other: French)
4. Add a node in English and translate it to French.
5. Delete the French language itself (not the French translation of the node).
6. View the node that had been created.Notes:
- The entity doesn't have to be nodes. It can happen on other entities. In my case, it's Blocks.
- It doesn't matter if the language deleted has a region/script extension (e.g. zh-hant, pt-pt).
- Step 6 doesn't need to be a full view. Anything that pulls up an entity to check its language will also do (e.g. view nodes in content admin).
- Step 5 is not limited to deleting the language via admin. The same effect happens withdrush cim
(e.g. delete language entity config, deploy code to environment, and dodrush deploy
on that environment).Now for the fun part:
- The potential cause of the issue is that there's content in the database that's still using the deleted language. This content is not cleaned up or at least converted into a representation that still works after deleting its language.
- The patch in #4 only works for the workflow that hitsEntityAccessControlHandler.php
. But in general, anything that pulls up the language entity from any entity and calls a method of that language entity will have this issue (i.e. any code that does$entity->language()->ANYMETHOD()
). I just did a quick search in both core and contrib of my project, and there a lot of this$entity->language()->ANYMETHOD()
pattern.
-\Drupal\Core\Entity\EntityInterface->language()
is NOT type-hinted as nullable but the implementation can return aNULL
.Potential fixes:
- Declare$entity->language()
to returnNULL
. This is true to the current behavior but would require everyone to null-check their language entities and would break API signatures.
- Have$entity->language()
to always return an object of\Drupal\Core\Language\LanguageInterface
(possibly represent "und", or however other APIs are representing "no language"). This keeps the signature and avoid having everyone null-check their language entities. But then this would also break everything that does check forNULL
. - 🇺🇸United States JasonSafro
We are also seeing the issue in Drupal 10.2.7. @fskruez wrote a really good comment on the scope of the problem:
- It is possible to create "orphaned" translations - translations of entities in languages that no longer exist
- Patching Drupal to buffer against "orphaned" translations would require 100+ code changes
The attached patch does not let Drupal function with orphaned translations. Instead, it stops Drupal from deleting a language if this will result in orphaned content. A ounce of prevention is worth a pound of cure?
- 🇮🇳India anandhi karnan Chennai
I was unable to reproduce the issue based on comment #11 in Drupal 10.3.x and 11.x.
I followed these steps:
1. Installed Drupal 11.x
2. Enabled the Languages and Content Translation modules.
3. Added the French language under /admin/config/regional/language.
4. Created a node that uses the second language.
5. Removed the second language from the site (/admin/config/regional/language).
6. Returned to the node view page that had been created.I am attaching a screen recording of the testing in Drupal 11.x. I followed the same steps for Drupal 10.3.x, but I was unable to reproduce the issue.
Please let me know if I am missing anything here.