Skip to content

Wrong exit code 11 ('No errors found') on projects with large vendor autoload (caused by an issue from php-src) #11679

@alies-dev

Description

@alies-dev

Description

Psalm returns exit code 11 even when reporting "No errors found!" on a project with a large vendor/ dependency tree. This affects both regular analysis and taint analysis. A fresh Laravel 12 project with the same Psalm version returns exit 0 correctly.

This is NOT taint-specific — regular psalm (without --taint-analysis) also returns exit 11 on the same project.

Psalm version

Psalm 6.15.1 (28dc127af1b5aecd52314f6f645bafc10d0e11f9)
PHP 8.4.18 (tested with and without JIT — same result)

Reproduction

Fresh Laravel 12 — exit 0 (correct):

composer create-project laravel/laravel psalm-test
cd psalm-test
composer require --dev vimeo/psalm:^6.15
vendor/bin/psalm --init
vendor/bin/psalm --taint-analysis --no-cache --no-progress
# No errors found!
# EXIT: 0 ✅

Large Laravel project — exit 11 (incorrect):

Using a minimal psalm-taint.xml that scans a single trivial file:

<?xml version="1.0"?>
<psalm
    xmlns="https://getpsalm.org/schema/config"
    errorLevel="1"
    resolveFromConfigFile="true"
>
    <projectFiles>
        <file name="psalm-taint-empty.php"/>
        <ignoreFiles>
            <directory name="vendor"/>
        </ignoreFiles>
    </projectFiles>
</psalm>

The scanned file is trivial:

<?php

declare(strict_types=1);

function psalmTaintTest(): string
{
    return 'hello';
}
php -d memory_limit=-1 vendor/bin/psalm --config=psalm-taint.xml --no-cache --no-progress
# No errors found!
# Psalm was able to infer types for 100% of the codebase
# EXIT: 11 ❌

Same result without --taint-analysis:

php -d memory_limit=-1 vendor/bin/psalm --config=psalm-taint.xml --no-cache --no-progress
# No errors found!
# EXIT: 11 ❌

Key differences between the two projects

Fresh Laravel Large project
Exit code 0 ✅ 11 ❌
Memory usage 316 MB 672 MB
Composer packages ~60 ~200+
Errors shown "No errors found!" "No errors found!"

Additional observations

  • Exit code 11 is not a signal (not 139/128+11) — Psalm returns it intentionally
  • Tested with JIT disabled — same result
  • With --debug flag: sometimes shows exit 0 and "No errors found!" (inconsistent)
  • The error is consistent regardless of which project file is scanned (tested with controllers, services, routes, and a trivial standalone file)
  • The bug appears to be triggered by the size/complexity of the Composer autoloader, not the scanned files themselves

Expected behavior

Exit code 0 when "No errors found!" is reported.

Actual behavior

Exit code 11 with "No errors found!" on projects with large vendor dependency trees.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions