pestphp/pest · error · BadMethodCallException
Method [%s] does not exist in [%s].
Error message
Method [%s] does not exist in [%s].
What it means
When you call an unknown method on an Expectation, Pest's __call tries three routes: a registered expectation, forwarding to PendingArchExpectation for arch-style methods (only when the value is not an object), or proxying to a real method on the underlying object (higher-order). If the method is none of those and the value is not an object, you get BadMethodCallException naming the method and the value's type. Typically this means a misspelled expectation name applied to a scalar/array/null value.
Source
Thrown at src/Expectation.php:320
return $this;
}
/**
* @param array<int, mixed> $parameters
* @return Expectation<TValue>|HigherOrderExpectation<Expectation<TValue>, TValue>
*/
public function __call(string $method, array $parameters): Expectation|HigherOrderExpectation|PendingArchExpectation|ArchExpectation
{
if (! self::hasMethod($method)) {
if (! is_object($this->value) && method_exists(PendingArchExpectation::class, $method)) {
$pendingArchExpectation = new PendingArchExpectation($this, []);
return $pendingArchExpectation->$method(...$parameters); // @phpstan-ignore-line
}
if (! is_object($this->value)) {
throw new BadMethodCallException(sprintf(
'Method [%s] does not exist in [%s].',
$method,
gettype($this->value)
));
}
/* @phpstan-ignore-next-line */
return new HigherOrderExpectation($this, call_user_func_array($this->value->$method(...), $parameters));
}
$closure = $this->getExpectationClosure($method);
$reflectionClosure = new \ReflectionFunction($closure);
$expectation = $reflectionClosure->getClosureThis();
if ($reflectionClosure->getReturnType()?->__toString() === ArchExpectation::class) {
return $closure(...$parameters);
}
View on GitHub (pinned to 1af74a215c)
Solutions
- Check the exact spelling against Pest's expectation API for your installed version (composer show pestphp/pest).
- If it is a custom expectation, make sure expect()->extend(...) runs before use — e.g., the file is listed in the tests directory structure Pest auto-loads (Expectations.php).
- For object proxies, ensure the underlying value really is an object with that method; for arrays/scalars, use the array/scalar expectation instead.
- If you need the method to exist, register it: expect()->extend('toFoo', fn () => ...).
Example fix
// before
expect('pest')->toUppercase(); // BadMethodCallException
// after
expect('PEST')->toBeUppercase(); Defensive patterns
Strategy: type-guard
Validate before calling
use Pest\Expectation;
if (! Expectation::hasMethod('toFoo')) {
expect()->extend('toFoo', fn (mixed $arg = null) => /* ... */);
}
expect($value)->toFoo(); Type guard
// object-proxy path: verify the underlying object has the method
if (is_object($value) && method_exists($value, 'getName')) {
expect($value)->getName()->toBe('Pest');
} else {
expect($value)->toBeObject(); // fail with a clear message
} Prevention
- Run Pint/an editor with Pest plugin so expectation names autocomplete and typos surface immediately.
- Register custom expectations in Expectations.php (or before first use) so they exist before any call.
- Pin the Pest version in CI to one whose expectation API matches your suite's usage.
When it happens
Trigger: expect('foo')->toUpercase() (misspelled toBeUppercase); expect(5)->toHaveItems(3) (method exists only on the object proxy path); calling a custom expectation before it was registered with expect()->extend(); calling an object-proxied method (e.g., ->getName()) on a scalar or array.
Common situations: Typos in expectation names (toBeTuure, toEqualRecursive); upgrading Pest and using an expectation introduced in a newer version; custom expectations defined in a Helpers/Expectations.php file that is not loaded; assuming an object-style proxy works on arrays.
Related errors
- Expectation value is not iterable.
- No sequence expectations defined.
- Sequence expectations are more than the iterable items.
- Unhandled match value.
- Expecting %s not %s %s.
AI-assisted analysis of pestphp/pest@1af74a215c (2026-08-21).
Data as JSON: /api/errors/74e7b233c8221b49.
Report an issue: GitHub.