vendor/ was seeded by copying af_readability's tree, so both plugins shipped ComposerAutoloaderInitb44cc79a… and ComposerStaticInitb44cc79a…. tt-rss's Preferences page loads every plugin on disk regardless of whether it is enabled, so the second require redeclared those classes and fataled the request. tt-rss blames whichever plugin lost the race -- the reported error named af_readability, which was the innocent party. Verified both autoloaders now load in the same process and the vendored Readability and Masterminds classes still resolve. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011sSJdftQx5bW5HZHgUKF3i
Local patches to the vendored dependencies
vendor/ is committed (tt-rss plugins ship their dependencies; there is no
composer in the app container), so upstream fixes we cannot wait for are applied
here and recorded below.
fivefilters/readability.php
src/Nodes/NodeTrait.php:371—callable $filterFn = null→?callable $filterFn = null. Implicitly nullable parameters are deprecated as of PHP 8.4, and the tt-rss app image is on PHP 8.5, so without this every extraction emits a deprecation notice.
composer autoloader class name
vendor/ was seeded by copying tt-rss-plugin-af-readability's tree, so both
plugins shipped the same generated bootstrap classes —
ComposerAutoloaderInitb44cc79a… and ComposerStaticInitb44cc79a….
tt-rss's Preferences page (Pref_Prefs::getPluginsList() → PluginHost::load_all())
loads every plugin on disk, enabled or not. The second require vendor/autoload.php
then redeclared those classes and PHP fataled, which tt-rss reports as:
Plugin af_readability has caused a PHP fatal error so it won't be loaded again in this session.
— naming whichever plugin lost the race, not the one at fault.
The hash in vendor/autoload.php, vendor/composer/autoload_real.php and
vendor/composer/autoload_static.php is therefore rewritten to
affulltext0000000000000000000001. Regenerating vendor/ with composer would
also fix it (composer derives the hash per-install); if you ever do, keep the
name distinct from any other tt-rss plugin's.