Skip to content

Language management

This page covers how this module interacts with the language list: protecting the locked language from deletion and handling the case where the locked language no longer exists.

Language deletion protection

When a lock language is set, deleting that language would leave all active configuration referencing a langcode that no longer exists. To prevent this, hook_entity_access returns AccessResult::forbidden() for delete operations on the locked language. This removes the delete link from the language admin UI automatically — no separate confirmation step is needed.

The locked language is also annotated with (Configuration language) in the language overview table to make it clear to administrators why it cannot be removed.

Stale lock protection

Despite the deletion protection above, it is still possible for the locked language to disappear — for example via drush, config sync, or direct database manipulation. getLockedLangcode() guards against this by validating the stored langcode against the list of currently installed languages before returning it. If the stored value no longer corresponds to a known language, the method returns NULL and the lock is silently treated as disabled. This prevents any config from being rewritten to a nonexistent language. So an accidental invalid lock cannot have wide reaching bad consequences this way.

The stale state persists in settings until an administrator explicitly changes or clears the lock on the settings form.

  • UI forms — form-based config entity creation and the langcode selector
  • Lock switch lifecycle — what happens to config when the lock language changes