mongodb/laravel-mongodb · error · InvalidArgumentException
Invalid search index definition for collection
Error message
Invalid search index definition for collection "%s", the "mappings" key is required. Find documentation at https://www.mongodb.com/docs/manual/reference/command/createSearchIndexes/#search-index-definition-syntax
What it means
createIndex() looks up the index definition from indexDefinitions (falling back to a default) and requires the 'mappings' key that Atlas Search mandates. A definition without 'mappings' is invalid for the createSearchIndexes command, so an InvalidArgumentException with a documentation link is thrown.
Solutions
- Add a 'mappings' key (with 'dynamic' or 'fields') to the index definition for that index name
- Fix the spelling of 'mappings' in the Scout search-index configuration
- Remove the custom definition to fall back to DEFAULT_DEFINITION if a default index is acceptable
- Follow the linked createSearchIndexes definition syntax docs
Example fix
// before 'indexes' => ['default' => ['synonyms' => []]], // after 'indexes' => ['default' => ['mappings' => ['dynamic' => true]]],
Defensive patterns
Strategy: validation
Validate before calling
foreach (config('scout.search-indexes', []) as $name => $def) {
if (!isset($def['mappings'])) {
throw new InvalidArgumentException("Search index '$name' is missing the required 'mappings' key.");
}
} Try / catch
try {
$engine->createIndex('default');
} catch (\InvalidArgumentException $e) {
config(['scout.search-indexes.default.mappings' => ['dynamic' => true]]);
$engine->createIndex('default');
} Prevention
- Validate scout index definitions in a config smoke test at boot
- Copy definitions from the documented createSearchIndexes syntax
- Watch for 'mapping' vs 'mappings' typos in review
When it happens
Trigger: Calling ScoutEngine::createIndex($name) when scout.search-indexes (indexDefinitions config) contains a definition for $name lacking the 'mappings' key.
Common situations: Typos like 'mapping' instead of 'mappings'; partially migrated Atlas index definitions copied from older configs; empty definitions arrays.
Understand the failure class
Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.
Related errors
- Cannot sort by a field named 'score' together with Atlas…
- Cannot sort by '_score' in ascending order; Atlas Search…
- Atlas search index operation time out after
- The MongoDB Scout collection
- Between $values must be a list with exactly two elements…
AI-assisted analysis of mongodb/laravel-mongodb@0634653039 (2026-09-15).
Data as JSON: /api/errors/148d22fb98b6bbbe.
Report an issue: GitHub.
Appendix: source
Thrown at src/Scout/ScoutEngine.php:454
/**
* Create the MongoDB Atlas Search index.
*
* Accepted options:
* - wait: bool, default true. Wait for the index to be created.
*
* @see Engine::createIndex()
*
* @param string $name Collection name
* @param array{wait?:bool} $options
*/
#[Override]
public function createIndex($name, array $options = []): void
{
assert(is_string($name), new TypeError(sprintf('Argument #1 ($name) must be of type string, %s given', get_debug_type($name))));
$definition = $this->indexDefinitions[$name] ?? self::DEFAULT_DEFINITION;
if (! isset($definition['mappings'])) {
throw new InvalidArgumentException(sprintf('Invalid search index definition for collection "%s", the "mappings" key is required. Find documentation at https://www.mongodb.com/docs/manual/reference/command/createSearchIndexes/#search-index-definition-syntax', $name));
}
// Ensure the collection exists before creating the search index
$this->database->createCollection($name);
$collection = $this->database->selectCollection($name);
$collection->createSearchIndex($definition, ['name' => self::INDEX_NAME]);
if ($options['wait'] ?? true) {
$this->wait(function () use ($collection) {
$indexes = $collection->listSearchIndexes([
'name' => self::INDEX_NAME,
'typeMap' => ['root' => 'bson'],
]);
return $indexes->current() && $indexes->current()->status === 'READY';
});
}View on GitHub (pinned to 0634653039)