Problem/Motivation

On Drupal 11.4.8, an admin menu-block page can render the first accessible child description in English even though the account administration language and the page interface language are Spanish or Brazilian Portuguese. The locale target exists, and a fresh TranslatableMarkup instance translates correctly in the same request. The existing menu definition has already memoized its English rendering.

Steps to reproduce

  1. Enable Language, Interface Translation and Database Logging. Keep English as the site default and add Spanish with the target for “View events that have recently been logged.”
  2. Enable Account administration pages language negotiation before the selected-language fallback. Use an account with permission to view reports and its preferred admin language set to Spanish.
  3. In a small test module, add an admin report-section route using \Drupal\system\Controller\SystemController::systemAdminMenuBlockPage, with the access site reports permission. Add its admin menu link under system.admin_reports, and move dblog.overview under that link as its first accessible child. Retain the automatic _access_admin_menu_block_page requirement.
  4. Request that section through an authenticated HTTP session. Observe the English child description on a Spanish page. Repeat with Brazilian Portuguese and warm menu caches.

Expected: the description uses the negotiated interface language. Actual: the first accessible child description remains English; other labels can be translated.

Investigation

A trace of the first description rendering follows this path:

LanguageRequestSubscriber::setLanguageOverrides
  ConfigurableLanguageManager::getCurrentLanguage
  LanguageNegotiationUserAdmin::getLangcode / isAdminPath
  AccessAwareRouter::match / checkAccess
  SystemAdminMenuBlockAccessCheck::hasAccessToChildMenuItems
  MenuLinkBase::getUrlObject
  MenuLinkDefault::getDescription
  TranslatableMarkup::render

The translator still uses English at this point. The description is resolved for a URL title attribute during access checking, before LanguageRequestSubscriber sets the negotiated language. The request-local menu definition later reuses that resolved object when SystemManager builds the admin block.

This reproduces through the actual LanguageRequestSubscriber and access-aware router in a kernel test as well as authenticated HTTP requests. Calling SystemManager directly after setting the translator language does not reproduce it. Database-backed caches reproduce it; Redis is not required.

Proposed resolution

Prevent route-access checks during language negotiation from permanently resolving menu descriptions in the default language. Preserve the child-link access checks. A scoped application workaround that reloads request-local menu definitions at the controller event restores the expected translations, but a core solution should address the early resolution itself.

Remaining tasks

Confirm on main, add a core regression test, and choose the appropriate fix in the negotiation/access/menu interaction. No core patch is proposed here.

User interface changes

Existing translated menu descriptions use the negotiated administration language.

API changes

None proposed.

Data model changes

None proposed.

Comments

jmcerda created an issue.