Call to a member function getId() on null

Created on 15 March 2021, over 3 years ago
Updated 1 August 2024, about 2 months ago

Problem

Error: Call to a member function getId() on null in /var/www/website/web/core/lib/Drupal/Core/Entity/EntityAccessControlHandler.php on line 63 #0 /var/www/website/web/core/modules/node/src/NodeAccessControlHandler.php(68): Drupal\Core\Entity\EntityAccessControlHandler->access(Object(Drupal\node\Entity\Node), 'view', Object(Drupal\Core\Session\AccountProxy), true)

Fix

$langcode = $entity->language()->getId();
to
$langcode = ($entity->language() ? $entity->language()->getId() : NULL);

Steps to reproduce

These are rough steps to reproduce based on comment #9.

1. Install Drupal
2. Enable Languages and Content Translation modules
3. Add a language
4. Add a node that uses the 2nd language
5. Remove the 2nd language from the site
6. View the node that had been created.

πŸ› Bug report
Status

Needs work

Version

11.0 πŸ”₯

Component
EntityΒ  β†’

Last updated about 1 hour ago

Created by

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • πŸ‡ΊπŸ‡Έ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 with drush cim (e.g. delete language entity config, deploy code to environment, and do drush 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 hits EntityAccessControlHandler.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 a NULL.

    Potential fixes:
    - Declare $entity->language() to return NULL. 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 for NULL.

  • πŸ‡ΊπŸ‡Έ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?

Production build 0.71.5 2024