pestphp/pest · error · MissingDependency

The [%s] feature requires [%s]. Please install it and try ag

Error message

The [%s] feature requires [%s]. Please install it and try again.

What it means

The toHaveSuspiciousCharacters arch expectation (including its negated form) relies on Spoofchecker from PHP's intl extension (ext-intl >= 2.0) to detect confusable/homoglyph identifiers. Pest checks class_exists(Spoofchecker::class) first and throws MissingDependency — 'The [toHaveSuspiciousCharacters] feature requires [ext-intl >= 2.0]. Please install it and try again.' — before scanning any file.

Source

Thrown at src/Expectations/OppositeExpectation.php:244

        /** @var Expectation<array<int, string>|string> $original */
        $original = $this->original;

        return Targeted::make(
            $original,
            fn (ObjectDescription $object): bool => array_filter(
                $methods,
                fn (string $method): bool => isset($object->reflectionClass) === false || $object->reflectionClass->hasMethod($method),
            ) === [],
            'to not have methods: '.implode(', ', $methods),
            FileLineFinder::where(fn (string $line): bool => str_contains($line, 'class')),
        );
    }

    public function toHaveSuspiciousCharacters(): ArchExpectation
    {
        if (! class_exists(Spoofchecker::class)) {
            throw new MissingDependency(__FUNCTION__, 'ext-intl >= 2.0');
        }

        $checker = new Spoofchecker;

        /** @var Expectation<array<int, string>|string> $original */
        $original = $this->original;

        return Targeted::make(
            $original,
            fn (ObjectDescription $object): bool => ! $checker->isSuspicious((string) file_get_contents($object->path)),
            'to not include suspicious characters',
            FileLineFinder::where(fn (string $line): bool => $checker->isSuspicious($line)),
        );
    }

    /**
     * @param  array<int, string>  $methods
     */

View on GitHub (pinned to 1af74a215c)

Solutions

  1. Install and enable ext-intl: docker-php-ext-install intl (plus icu-dev on Alpine), apt install php-intl (Debian/Ubuntu), brew install php (macOS), then restart PHP/CI runner.
  2. Enable an already-installed extension: uncomment extension=intl in php.ini and confirm with php -m | grep intl.
  3. If intl cannot be installed in that environment, remove or skip the toHaveSuspiciousCharacters expectation (mark it skipped when extension_loaded('intl') is false).

Example fix

# before (Dockerfile)
FROM php:8.3-cli
# vendor/bin/pest --tests arch -> MissingDependency
# after
FROM php:8.3-cli
RUN apt-get update && apt-get install -y libicu-dev \
    && docker-php-ext-install intl
Defensive patterns

Strategy: validation

Validate before calling

if (! extension_loaded('intl') || ! class_exists(Spoofchecker::class)) {
    test('arch: no suspicious characters')
        ->skip(! extension_loaded('intl'), 'ext-intl not installed');
}
// or guard before running the suite at all:
if (! extension_loaded('intl')) {
    fwrite(STDERR, "ext-intl is required for spoof-checking arch tests\n");
    exit(1);
}

Prevention

When it happens

Trigger: Running an architecture test that calls ->toHaveSuspiciousCharacters() or ->not->toHaveSuspiciousCharacters() on a PHP build compiled without intl; slim Docker images (alpine, php:*-cli) that ship without ext-intl; CI matrices where only some jobs install intl.

Common situations: Local macOS/Linux PHP built with --disable-intl; Alpine docker images requiring docker-php-ext-install intl; shared hosts where the extension is present but not enabled in php.ini; enabling spoof-checking rules in a shared arch pest file that all environments run.

Related errors


AI-assisted analysis of pestphp/pest@1af74a215c (2026-08-21). Data as JSON: /api/errors/eda07d76a6348fe5. Report an issue: GitHub.