laravel/framework · error · LogicException
Please implement the prunable method on your model.
Error message
Please implement the prunable method on your model.
What it means
The MassPrunable trait provides a default prunable() method that only throws this LogicException. MassPrunable deletes records in bulk via a single query (chunked delete) and requires the consuming model to override prunable() to return the query builder that selects which records to remove. Without an override, pruneAll() cannot proceed.
Source
Thrown at src/Illuminate/Database/Eloquent/MassPrunable.php:50
if ($count > 0) {
event(new ModelsPruned(static::class, $total));
}
} while ($count > 0);
return $total;
}
/**
* Get the prunable model query.
*
* @return \Illuminate\Database\Eloquent\Builder<static>
*
* @throws \LogicException
*/
public function prunable()
{
throw new LogicException('Please implement the prunable method on your model.');
}
}
View on GitHub (pinned to bd6b5437e6)
Solutions
- Implement prunable() on the model returning a Builder, e.g. public function prunable() { return static::where('created_at', '<', now()->subYear()); }.
- If you intended per-model pruning logic, use the Prunable trait instead of MassPrunable.
- Ensure the method returns a Builder (not a collection) and includes the where conditions selecting rows to prune.
Example fix
// before
class LogEntry extends Model {
use MassPrunable;
}
// after
class LogEntry extends Model {
use MassPrunable;
public function prunable()
{
return static::where('created_at', '<', now()->subMonth());
}
} Defensive patterns
Strategy: type-guard
Validate before calling
$reflection = new \ReflectionMethod($modelClass, 'prunable');
if ($reflection->getDeclaringClass()->getName() === \Illuminate\Database\Eloquent\MassPrunable::class) {
throw new \LogicException("{$modelClass} must override prunable() before pruning.");
} Type guard
function implementsPrunable(string $modelClass): bool {
return (new \ReflectionMethod($modelClass, 'prunable'))
->getDeclaringClass()->getName() !== \Illuminate\Database\Eloquent\MassPrunable::class;
} Prevention
- Always override prunable() the moment you add 'use MassPrunable;'.
- Run model:prune in a non-prod environment first to surface missing overrides.
- Document the override requirement in the trait adoption checklist.
When it happens
Trigger: Adding 'use MassPrunable;' to a model and then invoking Model::pruneAll() (typically via the model:prune artisan command) without overriding the prunable() method.
Common situations: Adopting the MassPrunable trait for faster pruning but forgetting the prunable() stub, or swapping from Prunable to MassPrunable and missing the override requirement.
Related errors
- Please implement the prunable method on your model.
- The command "%s" does not exist.
- Unable to determine command name from signature.
- Console component [%s] not found.
- The chunkById operation was aborted because the [{$alias}] c
AI-assisted analysis of laravel/framework@bd6b5437e6 (2026-08-06).
Data as JSON: /data/errors/39861b2b28dc9c41.json.
Report an issue: GitHub.