{"record":{"id":"528d2a2a5caaf943","repo":"laravel/framework","slug":"index-name-contains-invalid-characters","errorCode":null,"errorMessage":"Index name contains invalid characters.","messagePattern":"Index name contains invalid characters\\.","errorType":"exception","errorClass":"InvalidArgumentException","httpStatus":null,"severity":"error","filePath":"src/Illuminate/Database/Query/Grammars/MySqlGrammar.php","lineNumber":153,"sourceCode":"\n    /**\n     * Compile the index hints for the query.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  \\Illuminate\\Database\\Query\\IndexHint  $indexHint\n     * @return string\n     *\n     * @throws \\InvalidArgumentException\n     */\n    protected function compileIndexHint(Builder $query, $indexHint)\n    {\n        $index = $indexHint->index;\n\n        $indexes = array_map('trim', explode(',', $index));\n\n        foreach ($indexes as $i) {\n            if (! preg_match('/^[a-zA-Z0-9_$]+$/', $i)) {\n                throw new InvalidArgumentException('Index name contains invalid characters.');\n            }\n        }\n\n        return match ($indexHint->type) {\n            'hint' => \"use index ({$index})\",\n            'force' => \"force index ({$index})\",\n            default => \"ignore index ({$index})\",\n        };\n    }\n\n    /**\n     * Compile a group limit clause.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @return string\n     */\n    protected function compileGroupLimit(Builder $query)\n    {","sourceCodeStart":135,"sourceCodeEnd":171,"githubUrl":"https://github.com/laravel/framework/blob/e0f6eb3518ac29fbbca8529e97d0df7fc9f24481/src/Illuminate/Database/Query/Grammars/MySqlGrammar.php#L135-L171","documentation":"MySqlGrammar's compileIndexHint validates each comma-separated index name against /^[a-zA-Z0-9_$]+$/ before emitting USE INDEX / FORCE INDEX / IGNORE INDEX clauses. If any index name contains characters outside that set (spaces, hyphens, dots, backticks, etc.), an InvalidArgumentException is thrown before SQL compilation.","triggerScenarios":"Calling ->from('table', 'bad name') with an invalid index hint, or ->forceIndex('my-index'), ->useIndex('col.idx'), or any index hint method where the index name contains characters other than letters, digits, underscores, or dollar signs.","commonSituations":"Passing a hyphenated index name (e.g., 'user_email_index' is fine but 'user-email-index' is not). Including backtick-quoted or schema-qualified names. Copying index names from migration output that contain unusual characters.","solutions":["Rename the index in the migration to use only alphanumeric, underscore, and dollar-sign characters","Remove invalid characters from the index hint string: replace hyphens, spaces, and dots with underscores","If the index genuinely contains special characters, reference it via a raw SQL clause instead of the index hint API"],"exampleFix":"// before — hyphen in index name throws\nDB::table('orders')->forceIndex('order-status-idx')->where('status', 'pending')->get();\n\n// after — underscore-only name passes\nDB::table('orders')->forceIndex('order_status_idx')->where('status', 'pending')->get();","handlingStrategy":"validation","validationCode":"$indexName = 'user_email_idx';\nif (preg_match('/^[a-zA-Z0-9_$]+$/', $indexName)) {\n    DB::table('users')->forceIndex($indexName)->get();\n} else {\n    throw new \\InvalidArgumentException(\"Invalid index name: {$indexName}\");\n}","typeGuard":"function isValidIndexName(string $name): bool {\n    return (bool) preg_match('/^[a-zA-Z0-9_$]+$/', $name);\n}","tryCatchPattern":"try {\n    DB::table('users')->forceIndex($indexName)->get();\n} catch (\\InvalidArgumentException $e) {\n    if (str_contains($e->getMessage(), 'invalid characters')) {\n        $sanitized = preg_replace('/[^a-zA-Z0-9_$]/', '_', $indexName);\n        DB::table('users')->forceIndex($sanitized)->get();\n    } else {\n        throw $e;\n    }\n}","preventionTips":["Name indexes using only alphanumeric characters and underscores in migrations","Validate dynamic index names with preg_match before passing to forceIndex/useIndex/ignoreIndex","Avoid hyphens, dots, and spaces in index names across all database engines"],"tags":["index","mysql","validation","grammar"],"backgroundTag":null,"analyzedSha":"e0f6eb3518ac29fbbca8529e97d0df7fc9f24481","analyzedAt":"2026-08-11T20:52:37.562Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}