Problem/Motivation
The phpstan job is allow_failure: false in .gitlab-ci.yml, and it fails on 1.x itself. Because it fails on the target branch, every merge request also shows a red pipeline, whatever the MR changes.
That is not cosmetic. Two genuine CI failures sat unnoticed behind it — #3616634 was failing phpcs and #3609260 was failing cspell — because a red pipeline had stopped meaning anything.
Steps to reproduce
Look at the pipeline history for 1.x. It was green in June and has failed on phpstan, and only phpstan, ever since:
841396 success 1d7f8ba 2026-06-09 last green 917167 failed ff44ae0 2026-08-10 922098 failed 3f20f78 2026-08-13 934815 failed 704827d 2026-08-24 935009 failed de95931 2026-08-24 947591 failed c0c8a0d 2026-09-04 947706 failed 5692f16 2026-09-04 947733 failed 3ab5c54 2026-09-04 current
In every one of those runs composer, composer-lint, phpcs, cspell and phpunit pass.
Proposed resolution
The cause is not established, and it is worth being careful rather than blaming the obvious commit. No pipeline ran for two months between the last green run and the first red one, so several things changed at once:
ff44ae0is the only project commit in that window — the merge of #3548465, which added thelangfuse_feedbacksubmodule.mglaman/phpstan-drupal2.1.0 was released 2026-07-14, also in that window, and it adds rules. For example its "Logger assigned from LoggerChannelFactory in a class using DependencySerializationTrait" rule fires under 2.1.2 but not under 2.0.15 on identical code.- Several
phpstan/phpstan2.2.x releases landed in the same window.
The job installs the analyser unpinned:
composer require --dev phpstan/phpstan --ignore-platform-reqs || trueSo a new upstream release changes the analysis with no commit to this project, which on its own can turn a green pipeline red. It also means the version CI used is not reproducible from the repository. Meanwhile composer.json pins phpstan/phpstan: ^1.0 in require-dev and the job overrides it, so local runs and CI runs are not even on the same major version. That mismatch should be reconciled either way.
Remaining tasks
- Read the actual
phpstanjob log for the real findings, rather than inferring them from a local run. Local runs are not representative: CI has noai,ai_agents,search_apioropenai-phpinstalled, since all four aresuggestrather thanrequire, and their absence changes whichignoreErrorspatterns inphpstan.neonmatch. - Fix the findings.
- Pin the analyser so CI and local agree and the result stops moving on its own.
- Confirm green on a real pipeline, not just locally.
A branch is already prepared for the code side. It drops the CI-visible count from 9 to 3 by returning new static() from the four container factories (with @phpstan-consistent-constructor, without which new static() trips Unsafe usage of new static()) and removing two dead method_exists() guards in LangfuseSyncSubscriber, where the SDK's ObservationInterface already declares both methods. The remaining three are deliberately left: two in LangFuseAiLoggingSubscriber and one needing a langfuse_example.services.yml.
User interface changes
None.
Issue fork langfuse-3620878
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #4
nikro commented