Skip to content

Fix autoloader priority to prevent loading old framework classes from packages#6243

Draft
Copilot wants to merge 5 commits intomainfrom
copilot/fix-readme-generation-error
Draft

Fix autoloader priority to prevent loading old framework classes from packages#6243
Copilot wants to merge 5 commits intomainfrom
copilot/fix-readme-generation-error

Conversation

Copy link
Contributor

Copilot AI commented Feb 14, 2026

The readme generation workflow fails because the autoloader loads old framework classes from package vendor directories instead of from the WP-CLI phar.

Root Cause

When WP-CLI runs from a phar and loads packages (e.g., scaffold-package-command), those packages may have their own vendor/wp-cli/wp-cli directory with old framework code. The autoloader registration order causes the issue:

  1. Framework autoloader is registered (appended to end of queue)
  2. Package Composer autoloader is registered (appended to end of queue, now has priority)

This results in old framework classes from package vendor directories being loaded instead of from the phar, leading to errors like "Call to undefined method WP_CLI\Dispatcher\RootCommand::get_hook()".

Changes

Autoloader Priority Fix (Primary)

  • Modified Autoloader::register(): Added optional $prepend parameter to support prepending the autoloader to the queue
  • Updated IncludeFrameworkAutoloader: Now calls $autoloader->register(true) to prepend the framework autoloader

This ensures framework classes from the phar are always loaded first, even when packages have old wp-cli/wp-cli versions in their vendor directories.

// In Autoloader.php
public function register( $prepend = false ) {
    spl_autoload_register( [ $this, 'autoload' ], true, $prepend );
}

// In IncludeFrameworkAutoloader.php
$autoloader->register( true );  // Prepend to give priority

Backward Compatibility Fix

  • Initialize $hook = '' in RootCommand::__construct(): Ensures backward compatibility for any code that might instantiate RootCommand directly or when older framework versions are temporarily loaded

Test Coverage

  • Added features/autoloader-priority.feature: Comprehensive Behat tests with 3 scenarios to verify the fix:
    1. Verify framework autoloader is prepended - Checks that WP_CLI\Autoloader is registered in the autoloader queue
    2. Old framework class should not break cmd-dump - Simulates a package with an old RootCommand class (without get_hook()) in its vendor directory and verifies the framework version from the phar is loaded instead
    3. Framework classes work correctly with get_hook() method - Verifies RootCommand has get_hook() and returns the correct empty string value

Testing

  • ✅ All linting, code style, and static analysis checks pass
  • ✅ All unit tests pass (52 CommandFactory tests)
  • ✅ All CLI feature tests pass (4 scenarios, 20 steps)
  • ✅ All autoloader priority tests pass (3 scenarios, 18 steps)
  • ✅ Manual verification confirms wp cli cmd-dump works correctly
  • ✅ Code review found no issues
  • ✅ Security scan found no issues

The fix properly addresses the autoloader conflict, ensuring that framework classes from the phar are always loaded first, regardless of what packages have in their vendor directories. The new tests prevent regressions by simulating real-world scenarios where packages might have outdated wp-cli/wp-cli dependencies.

Original prompt

This section details on the original issue you should resolve

<issue_title>Error in readme generation workflow</issue_title>
<issue_description>## Bug Report

Describe the current, buggy behavior

https://github.com/wp-cli/language-command/actions/runs/9379802233/job/25825470872#step:12:114

Error:

PHP Fatal error:  Uncaught Error: Call to undefined method WP_CLI\Dispatcher\RootCommand::get_hook() in phar:///usr/local/bin/wp/vendor/wp-cli/wp-cli/php/commands/src/CLI_Command.php:42

Describe what you would expect as the correct outcome

Generate readme correctly

Let us know what environment you are running this on

OS:	Darwin 22.6.0 Darwin Kernel Version 22.6.0: Mon Apr 22 20:54:28 PDT 2024; root:xnu-8796.141.3.705.2~1/RELEASE_X86_64 x86_64
Shell:	/bin/zsh
PHP binary:	/usr/local/bin/php
PHP version:	8.2.19
php.ini used:	/usr/local/etc/php/8.2/php.ini
MySQL binary:	/usr/local/mysql-8.0.36-macos14-x86_64/bin/mysql
MySQL version:	mysql  Ver 8.0.36 for macos14 on x86_64 (MySQL Community Server - GPL)
SQL modes:	
WP-CLI root dir:	/Users/nilambarsharma/Code/wp-cli-dev/wp-cli
WP-CLI vendor dir:	/Users/nilambarsharma/Code/wp-cli-dev/wp-cli/vendor
WP_CLI phar path:	
WP-CLI packages dir:	/Users/nilambarsharma/.wp-cli/packages/
WP-CLI cache dir:	/Users/nilambarsharma/.wp-cli/cache
WP-CLI global config:	
WP-CLI project config:	/Users/nilambarsharma/Sites/staging/wp-cli.local.yml
WP-CLI version:	2.11.0-alpha

</issue_description>

Comments on the Issue (you are @copilot in this section)

@swissspidy Previous lengthy discussion about this:

It's not isolated to this package alone. Basically all packages are affected.

It seemed like an autoloader issue to me.

The readme generation workflow basically does this:

  1. Install WP-CLI nightly phar
  2. Run wp package install "wp-cli/scaffold-package-command:^2"
  3. Regenerate readme

Now, scaffold-package-command requires framework version 2.11.x, which was done in wp-cli/scaffold-package-command#243. And the WP-CLI nightly phar also requires framework version 2.11.x

However, this particular command here does not.

So while in theory you would think the WP-CLI Phar loads the correct framework version, for some reason it loads classes from language-command/vendor/wp-cli/wp-cli/..., which is the old version.

PHP Fatal error:  Uncaught Error: Call to undefined method WP_CLI\Dispatcher\RootCommand::get_hook() in phar:///usr/local/bin/wp/vendor/wp-cli/wp-cli/php/commands/src/CLI_Command.php:42
Stack trace:
wp-cli/wp-cli#0 phar:///usr/local/bin/wp/vendor/wp-cli/wp-cli/php/commands/src/CLI_Command.php(555): CLI_Command->command_to_array()
wp-cli/language-command#1 [internal function]: CLI_Command->cmd_dump()
wp-cli/language-command#2 /home/runner/work/language-command/language-command/vendor/wp-cli/wp-cli/php/WP_CLI/Dispatcher/CommandFactory.php(100): call_user_func()
wp-cli/language-command#3 [internal function]: WP_CLI\Dispatcher\CommandFactory::WP_CLI\Dispatcher\{closure}()
wp-cli/language-command#4 /home/runner/work/language-command/language-command/vendor/wp-cli/wp-cli/php/WP_CLI/Dispatcher/Subcommand.php(497): call_user_func()
wp-cli/language-command#5 phar:///usr/local/bin/wp/vendor/wp-cli/wp-cli/php/WP_CLI/Runner.php(441): WP_CLI\Dispatcher\Subcommand->invoke()
wp-cli/language-command#6 phar:///usr/local/bin/wp/vendor/wp-cli/wp-cli/php/class-wp-cli.php(1394): WP_CLI\Runner->run_command()
wp-cli/language-command#7 /home/runner/.wp-cli/packages/vendor/wp-cli/scaffold-package-command/src/ScaffoldPacka in phar:///usr/local/bin/wp/vendor/wp-cli/wp-cli/php/commands/src/CLI_Command.php on line 42

That doesn't really make sense to me. Why is the Phar loading stuff from the current directory?

@schlessera Could you please enlighten us?</comment_new>
<comment_new>@BrianHenryIE
Is this happening only on GitHub or is it reproducible locally?

I had a very similar problem recently and came across others with also very similar problems: InterNACHI/modular#92 (comment)

I wouldn't be surprised if this is a Composer / GitHub Actions issue that will be fixed without changes on our end.</comment_new>


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

@codecov
Copy link

codecov bot commented Feb 14, 2026

Codecov Report

❌ Patch coverage is 0% with 3 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
php/WP_CLI/Autoloader.php 0.00% 2 Missing ⚠️
...hp/WP_CLI/Bootstrap/IncludeFrameworkAutoloader.php 0.00% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix error in readme generation workflow Initialize $hook property in RootCommand constructor Feb 14, 2026
Copilot AI requested a review from swissspidy February 14, 2026 22:38
@swissspidy

This comment was marked as resolved.

…ages

Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com>

This comment was marked as resolved.

Copilot AI changed the title Initialize $hook property in RootCommand constructor Fix autoloader priority to prevent loading old framework classes from packages Feb 15, 2026
@swissspidy

This comment was marked as resolved.

Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com>

This comment was marked as resolved.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug command:cli Related to 'cli' command command:cli-cmd-dump Related to 'cli cmd-dump' command command:cli-utils

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Error in readme generation workflow

2 participants

Comments