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
- 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.
- Enable an already-installed extension: uncomment extension=intl in php.ini and confirm with php -m | grep intl.
- 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
- Declare ext-intl in composer.json require-dev so Composer fails early when it is absent.
- Bake ext-intl into Docker images and CI matrices (docker-php-ext-install intl, apt install php-intl).
- Verify with php -m | grep intl in CI bootstrap when arch tests use Spoofchecker.
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
- The test directory [%s] does not exist.
- Cached failure
- The test expects [%d] argument(s), but the dataset only prov
- Expectation value is not iterable.
- No sequence expectations defined.
AI-assisted analysis of pestphp/pest@1af74a215c (2026-08-21).
Data as JSON: /api/errors/eda07d76a6348fe5.
Report an issue: GitHub.