laravel/framework · error · BadMethodCallException
Call to undefined method
Error message
Call to undefined method %s::%s()
What it means
PendingHasThroughRelationship is the intermediate object returned by the has?Through style 'through()' helper. Its __call magic only forwards methods starting with 'has' (e.g. hasPosts) to has(); any other method call is treated as undefined and throws BadMethodCallException. This surfaces typos and wrong chaining in has-one/has-many-through definitions.
Solutions
- Use the has() method (or a has-prefixed dynamic method) on the pending object: $this->through($relation)->has('comments').
- Verify the distant relationship callback you intend to call actually maps to a 'has' method.
- Re-read the PendingHasThroughRelationship API to confirm the only dynamic surface is has*.
Example fix
// before
return $this->through($local)->comments(); // throws
// after
return $this->through($local)->has('comments');
// or via the dynamic 'has' prefix
return $this->through($local)->hasComments(); Defensive patterns
Strategy: validation
Validate before calling
// Only methods beginning with 'has' are valid on a PendingHasThroughRelationship
if (! str_starts_with($method, 'has')) {
throw new \BadMethodCallException("Only has* methods are valid on PendingHasThroughRelationship, got: {$method}");
}
return $this->through($local)->{$method}(...$args); Type guard
function isValidHasThroughCall(string $method): bool {
return str_starts_with($method, 'has');
} Prevention
- Always terminate a through() chain with has() (or a has* dynamic method).
- Re-read PendingHasThroughRelationship - the only dynamic surface is has*.
- If you need other behaviour, define the relationship with hasManyThrough/hasOneThrough directly.
When it happens
Trigger: Writing return $this->through($relation)->someOtherMethod(...) where someOtherMethod does not start with 'has', or chaining a non-has method onto the result of through().
Common situations: Misremembering the fluent API for has-through; copy-paste from a normal relation definition; IDE autocomplete suggesting a wrong method; typo like 'thas' instead of 'has'.
Related errors
- Collection given to whereAttachedTo method may not be empty.
- Collection given to whereBelongsTo method may not be empty.
- Invalid aggregate [ ] used within ofMany relation…
- Model attribute value is an object but does not have a…
- The provided value may not be null.
AI-assisted analysis of laravel/framework@e0f6eb3518 (2026-08-11).
Data as JSON: /api/errors/8c427cecfe196d45.
Report an issue: GitHub.
Appendix: source
Thrown at src/Illuminate/Database/Eloquent/PendingHasThroughRelationship.php:115
return $returnedRelation;
}
/**
* Handle dynamic method calls into the model.
*
* @param string $method
* @param array $parameters
* @return mixed
*
* @throws \BadMethodCallException
*/
public function __call($method, $parameters)
{
if (Str::startsWith($method, 'has')) {
return $this->has((new Stringable($method))->after('has')->lcfirst()->toString());
}
throw new BadMethodCallException(sprintf(
'Call to undefined method %s::%s()', static::class, $method
));
}
}
View on GitHub (pinned to e0f6eb3518)