mongodb/laravel-mongodb · error · LogicException
The MongoDB Scout collection
Error message
The MongoDB Scout collection "%s.%s" must use a different collection from the collection name of the model "%s". Set the "scout.prefix" configuration or use a distinct MongoDB database
What it means
The Scout engine must store search documents in a collection distinct from the model's own MongoDB collection; otherwise indexing would overwrite application data. getIndexableCollection() throws a LogicException when the model uses the same MongoDB connection/database and its table equals indexableAs() (no prefix separation).
Solutions
- Set the 'scout.prefix' config value (e.g. 'search_') so indexed collections are named differently
- Point the Scout engine at a distinct MongoDB database
- Change the model's table or searchableAs() so it differs from indexableAs()
- Use a separate MongoDB connection for the Scout engine
Example fix
// before
// config/scout.php: 'prefix' => env('SCOUT_PREFIX', '')
// after
'scout.prefix' => env('SCOUT_PREFIX', 'search_') // e.g. SCOUT_PREFIX=search_ in .env Defensive patterns
Strategy: validation
Validate before calling
$conn = $model->getConnection();
if ($conn instanceof \MongoDB\Laravel\Connection
&& $conn->getDatabaseName() === config('scout.mongodb.database')
&& $model->getTable() === $model->indexableAs()) {
throw new \LogicException('Set scout.prefix or use a distinct database before indexing.');
} Try / catch
try {
$model->searchable();
} catch (\LogicException $e) {
if (str_contains($e->getMessage(), 'must use a different collection')) {
logger()->error('Configure scout.prefix or a separate Scout database.');
}
throw $e;
} Prevention
- Set SCOUT_PREFIX in .env for every MongoDB Scout deployment
- Point Scout at a dedicated MongoDB database separate from application data
- Add a boot-time assertion that indexableAs() differs from the model table
When it happens
Trigger: Calling update(), delete(), or flush() on a searchable model whose connection is a MongoDB Connection, whose database name equals the Scout engine's database, and whose table === indexableAs() (i.e. scout.prefix is empty).
Common situations: Fresh setups where scout.prefix was never configured; models whose searchIndexableAs/table naming collides; pointing Scout and the app at the same database without a prefix.
Understand the failure class
Background: "missing required config value" errors: why libraries refuse to start when a configuration key is empty, unset, or blank — this error's family across 48 libraries.
Related errors
- Cannot sort by a field named 'score' together with Atlas…
- Cannot sort by '_score' in ascending order; Atlas Search…
- Invalid search index definition for collection
- Atlas search index operation time out after
- Lock lottery must be a couple of integers [$chance, $total]…
AI-assisted analysis of mongodb/laravel-mongodb@0634653039 (2026-09-15).
Data as JSON: /api/errors/6015b2c1abe5cb6a.
Report an issue: GitHub.
Appendix: source
Thrown at src/Scout/ScoutEngine.php:515
return $this->database->selectCollection($model->searchableAs());
}
/** Get the MongoDB collection used to index the provided model */
private function getIndexableCollection(Model|EloquentCollection $model): MongoDBCollection
{
if ($model instanceof EloquentCollection) {
$model = $model->first();
}
assert($model instanceof Model);
assert(method_exists($model, 'indexableAs'), sprintf('Model "%s" must use "%s" trait', $model::class, Searchable::class));
if (
$model->getConnection() instanceof Connection
&& $model->getConnection()->getDatabaseName() === $this->database->getDatabaseName()
&& $model->getTable() === $model->indexableAs()
) {
throw new LogicException(sprintf('The MongoDB Scout collection "%s.%s" must use a different collection from the collection name of the model "%s". Set the "scout.prefix" configuration or use a distinct MongoDB database', $this->database->getDatabaseName(), $model->indexableAs(), $model::class));
}
return $this->database->selectCollection($model->indexableAs());
}
private static function serialize(mixed $value): mixed
{
if ($value instanceof DateTimeInterface) {
return new UTCDateTime($value);
}
if ($value instanceof Serializable || ! is_iterable($value)) {
return $value;
}
// Convert Laravel Collections and other Iterators to arrays
if ($value instanceof Traversable) {
$value = iterator_to_array($value);View on GitHub (pinned to 0634653039)