laravel/framework · error · LogicException
%s::%s must return a relationship instance, but "null" was r
Error message
%s::%s must return a relationship instance, but "null" was returned. Was the "return" keyword used?
What it means
getRelationshipFromMethod() calls the relation method and checks the result. If it returns exactly null, the most common cause is a missing 'return' keyword inside the method body, so the framework's hint message points at that exact mistake.
Source
Thrown at src/Illuminate/Database/Eloquent/Concerns/HasAttributes.php:641
throw new LazyLoadingViolationException($this, $key);
}
/**
* Get a relationship value from a method.
*
* @param string $method
* @return mixed
*
* @throws \LogicException
*/
protected function getRelationshipFromMethod($method)
{
$relation = Relation::withConstraintsForNestedRelation(fn () => $this->$method());
if (! $relation instanceof Relation) {
if (is_null($relation)) {
throw new LogicException(sprintf(
'%s::%s must return a relationship instance, but "null" was returned. Was the "return" keyword used?', static::class, $method
));
}
throw new LogicException(sprintf(
'%s::%s must return a relationship instance.', static::class, $method
));
}
return tap($relation->getResults(), function ($results) use ($method) {
$this->setRelation($method, $results);
});
}
/**
* Determine if a get mutator exists for an attribute.
*
* @param string $keyView on GitHub (pinned to bd6b5437e6)
Solutions
- Add the missing 'return' before the relation builder call.
- Run phpstan/pint locally; configure larastan to flag missing returns.
- Double-check every method that returns HasMany/BelongsTo etc. ends with 'return $this->...'.
Example fix
// before
public function comments()
{
$this->hasMany(Comment::class); // no return
}
// after
public function comments()
{
return $this->hasMany(Comment::class);
} Defensive patterns
Strategy: type-guard
Validate before calling
// Static analysis is the real guard; at runtime, inspect the method
$ref = new \ReflectionMethod($model, $relation);
if (! str_contains((string) $ref->getBodyText() ?? '', 'return')) {
throw new \LogicException("{$relation}() may be missing 'return'");
} Type guard
function relationReturnsInstance(object $model, string $method): bool
{
$r = $model->{$method}();
return $r instanceof \Illuminate\Database\Eloquent\Relations\Relation;
} Try / catch
try {
return $model->{$relation};
} catch (\LogicException $e) {
if (str_contains($e->getMessage(), '"null" was returned')) {
// tell developer to add 'return' in the relation method
}
throw $e;
} Prevention
- Run Larastan/phpstan level 6+ to catch missing returns statically.
- Every relation method must end with 'return $this->...Relation(...)'.
- Add a unit test that asserts each relation method returns a Relation instance.
When it happens
Trigger: Defining a relation method without 'return': public function comments() { $this->hasMany(Comment::class); } and then accessing $model->comments.
Common situations: Copy-paste error omitting 'return'; IDE auto-format that drops the keyword; refactoring a method body and forgetting to keep the return; static analyzers (phpstan) not yet run on the file.
Related errors
- %s::%s must return a relationship instance.
- Attempted to lazy load [{$relation}] on model [{$class}] but
- No morph map defined for model [{$class}].
- The chunkById operation was aborted because the [{$alias}] c
- The lazyById operation was aborted because the [{$alias}] co
AI-assisted analysis of laravel/framework@bd6b5437e6 (2026-08-06).
Data as JSON: /data/errors/fe1ac43dbd44f93c.json.
Report an issue: GitHub.