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:

  • ff44ae0 is the only project commit in that window — the merge of #3548465, which added the langfuse_feedback submodule.
  • mglaman/phpstan-drupal 2.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/phpstan 2.2.x releases landed in the same window.

The job installs the analyser unpinned:

composer require --dev phpstan/phpstan --ignore-platform-reqs || true

So 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 phpstan job log for the real findings, rather than inferring them from a local run. Local runs are not representative: CI has no ai, ai_agents, search_api or openai-php installed, since all four are suggest rather than require, and their absence changes which ignoreErrors patterns in phpstan.neon match.
  • 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

Command icon 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

nikro created an issue. See original summary.

  • nikro committed fc07534c on 1.x
    fix: #3620878 clear the phpstan findings and pin the analyser to the...
nikro’s picture

Status: Active » Fixed

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.