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

  1. Add a 'mappings' key (with 'dynamic' or 'fields') to the index definition for that index name
  2. Fix the spelling of 'mappings' in the Scout search-index configuration
  3. Remove the custom definition to fall back to DEFAULT_DEFINITION if a default index is acceptable
  4. 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

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


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)