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 Prunable trait (per-model delete-based pruning) provides a default prunable() that throws this LogicException. Unlike MassPrunable, Prunable deletes row-by-row after chunking, but still requires the model to override prunable() to return the query selecting records to prune.
Source
Thrown at src/Illuminate/Database/Eloquent/Prunable.php:59
}
});
event(new ModelsPruned(static::class, $total));
});
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.');
}
/**
* Prune the model in the database.
*
* @return bool|null
*/
public function prune()
{
$this->pruning();
return static::isSoftDeletable()
? $this->forceDelete()
: $this->delete();
}
/**
* Prepare the model for pruning.View on GitHub (pinned to bd6b5437e6)
Solutions
- Implement public function prunable() returning a Builder that selects the records to prune.
- Confirm the trait in use matches your intent (MassPrunable for bulk, Prunable for per-model pruning hooks).
- Implement the pruning() hook if you also need side effects before each delete.
Example fix
// before
class Document extends Model {
use Prunable;
}
// after
class Document extends Model {
use Prunable;
public function prunable()
{
return static::where('updated_at', '<', now()->subYear());
}
} Defensive patterns
Strategy: type-guard
Validate before calling
$reflection = new \ReflectionMethod($modelClass, 'prunable');
if ($reflection->getDeclaringClass()->getName() === \Illuminate\Database\Eloquent\Prunable::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\Prunable::class;
} Prevention
- Override prunable() whenever you add 'use Prunable;'.
- Run model:prune in staging first to catch missing overrides.
- Implement pruning() for any per-model side effects.
When it happens
Trigger: Adding 'use Prunable;' to a model and running Model::pruneAll() or model:prune without overriding prunable().
Common situations: Adopting Prunable for cleanup tasks and forgetting the override; switching between MassPrunable and Prunable and missing the method; artisan model:prune failing on a newly-tagged model.
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/4b9c97dc8d6fb337.json.
Report an issue: GitHub.