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 ships a default prunable() that throws, signaling the developer must override it on their model to declare which records are prunable. MassPrunable.pruneAll() calls prunable() to obtain the base query; without an override there is nothing to prune and the trait refuses to run. This is the trait's contract enforcement mechanism.
Solutions
- Implement prunable() on the model returning an Eloquent Builder, e.g. public function prunable() { return static::where('created_at', '<=', now()->subYear()); }.
- Confirm you used MassPrunable (bulk delete) intentionally; the plain Prunable trait also requires this method and deletes row by row.
- Re-run php artisan model:prune after adding the method.
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: validation
Validate before calling
// Before scheduling model:prune, verify the trait contract is satisfied
$reflection = new \ReflectionMethod($modelClass, 'prunable');
if ($reflection->getDeclaringClass()->getName() === \Illuminate\Database\Eloquent\MassPrunable::class) {
throw new \RuntimeException("{$modelClass} uses MassPrunable without overriding prunable()");
} Type guard
function overridesPrunable(string $modelClass): bool {
$r = new \ReflectionMethod($modelClass, 'prunable');
return $r->getDeclaringClass()->getName() !== \Illuminate\Database\Eloquent\MassPrunable::class;
} Prevention
- Always add a prunable() method whenever you add 'use MassPrunable;'.
- Add a CI/static-analysis rule or a boot-time assertion that any model using the trait overrides prunable().
- Run 'php artisan model:prune --pretend' to exercise the code path before scheduling it.
When it happens
Trigger: Adding 'use MassPrunable;' to a model and calling Model::pruneAll() without defining a prunable() method that returns a Builder.
Common situations: Setting up the prunable:console command for the first time; forgetting to implement prunable() after adopting the trait; copying a model skeleton that omits the method.
Related errors
- Please implement the prunable method on your model.
- Add fillable property
- Add [ ] to fillable property to allow mass assignment on […
- Attempted to batch job
- Call to undefined cast
AI-assisted analysis of laravel/framework@e0f6eb3518 (2026-08-11).
Data as JSON: /api/errors/39861b2b28dc9c41.
Report an issue: GitHub.
Appendix: 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 e0f6eb3518)