Problem/Motivation

On Drupal core 11.4.0, loading the extension list (e.g. visiting any admin page, drush commands, cache rebuilds) emits a PHP warning for every theme:

Warning: Undefined property: Drupal\Core\Extension\Theme::$origin
in git_deploy_system_info_alter() (line 32 of modules/contrib/git_deploy/git_deploy.module).

git_deploy_system_info_alter() reads the dynamic origin property off the $file extension object:

if (empty($info['hidden']) && (empty($info['version']) || ($file->origin == 'core' ? ...
origin is a dynamic property — core only sets it in ExtensionDiscovery::scanDirectory() ($extension->origin = $dir;). It is not declared on Extension/Theme.

What changed in 11.4: ExtensionList::doList() now re-subclasses the extension before invoking hook_system_info_alter():

// 11.4 core: core/lib/Drupal/Core/Extension/ExtensionList.php
foreach ($extensions as $name => $extension) {
  $extension->info = $this->createExtensionInfo($extension);
  $extension = $this->subClassExtension($extension);   // NEW in 11.4
  $extensions[$name] = $extension;
  $this->moduleHandler->alter('system_info', $extension->info, $extension, $this->type);
}

For themes, ThemeExtensionList::subClassExtension() re-instantiates the object with new Theme(...), which does not carry over the dynamic origin property:

protected function subClassExtension(Extension $extension): Theme {
  return new Theme($this->root, $extension->getPathname(), $extension->info, $extension->getExtensionFilename());
}

So the object handed to hook_system_info_alter() for themes no longer has origin, and reading $file->origin warns. In 11.3.x and earlier, doList() passed the original scanned object (which had origin), so the warning did not occur. Modules are unaffected because they are not re-subclassed the same way.

Steps to reproduce

  1. Install a site on Drupal core 11.4.0 with git_deploy:^2.6 enabled.
  2. Ensure a theme is present (any theme; core themes reproduce it).
  3. Rebuild caches / visit an admin page, or run drush cr.
  4. Observe the Undefined property: Drupal\Core\Extension\Theme::$origin warnings (one per theme).

Proposed resolution

Don't depend on the (never-guaranteed) dynamic origin property. Derive core-ness from the extension path when origin is absent, which works across all supported core versions:

$origin = $file->origin ?? (str_starts_with($file->getPath(), 'core/') ? 'core' : '');
Then use the local $origin variable instead of $file->origin throughout the function.

Remaining tasks

  • Review the path-based fallback (str_starts_with($file->getPath(), 'core/')) as the core-detection heuristic.
  • Confirm no regression on Drupal 10 / 11.3 (where origin is still populated — the ?? keeps the existing behavior).
  • Commit the fix / roll a new release.

User interface changes

none

API changes

none

Data model changes

none

Comments

andrewtur created an issue. See original summary.

andrewtur’s picture

Issue summary: View changes