laravel/framework · error · InvalidArgumentException
A class already exists.
Error message
A {$className} class already exists. What it means
MigrationCreator::ensureMigrationDoesntAlreadyExist guards against duplicate migration class names. After optionally require_once-ing the existing migration files in the target path, it calls class_exists() on the StudlyCase class name derived from the migration name; if that class is already declared in the PHP runtime, creation aborts with InvalidArgumentException. The check is global to the process, so a class loaded from any source counts as a collision.
Solutions
- Choose a more specific migration name (e.g. add_status_to_users_table) so the derived class name is unique.
- Delete or rename the pre-existing migration file that owns the colliding class name, then re-run.
- If the class is only resident because a previous command kept it in memory, re-run make:migration in a fresh PHP process.
Example fix
// before php artisan make:migration create_users_table // after php artisan make:migration add_status_to_users_table --table=users
Defensive patterns
Strategy: validation
Validate before calling
// Before calling MigrationCreator::create(), derive the class name the same way and check it.
$className = Str::studly(preg_replace('/^(\d{4}_\d{2}_\d{2}_)?/', '', $name)); // mimic getClassName
if (class_exists($className)) {
throw new RuntimeException("Migration class {$className} already exists; pick a new name.");
} Prevention
- Adopt a naming convention that includes intent (add_X, create_Y, drop_Z) so collisions are unlikely.
- Delete obsolete migration files rather than recreating them with the same name.
- Run make:migration in a fresh PHP process in long-running tools (e.g. test runners) to avoid stale class declarations.
When it happens
Trigger: Calling MigrationCreator::create($name, $path) — or `php artisan make:migration <name>` — where the derived class name (e.g. CreateUsersTable for name 'create_users_table') is already loaded. The collision can come from a same-named file in migrationPath, or from a class loaded earlier in the same PHP process.
Common situations: Re-running make:migration with the same name after a typo fix; two migration files mapping to the same Studly class name; migrations already required by a test bootstrap or an earlier artisan command in the same process; an old file left in place while recreating it.
Related errors
- Database was not created. Aborting migration.
- Index [ ] does not exist.
- Invalid database connection
- Method [run] missing from '.get_class($this)
- Schema dumping is not supported when using SQL Server.
AI-assisted analysis of laravel/framework@e0f6eb3518 (2026-08-11).
Data as JSON: /api/errors/2c3643b32821dc6b.
Report an issue: GitHub.
Appendix: source
Thrown at src/Illuminate/Database/Migrations/MigrationCreator.php:109
*
* @param string $name
* @param string|null $migrationPath
* @return void
*
* @throws \InvalidArgumentException
*/
protected function ensureMigrationDoesntAlreadyExist($name, $migrationPath = null)
{
if (! empty($migrationPath)) {
$migrationFiles = $this->files->glob($migrationPath.'/*.php');
foreach ($migrationFiles as $migrationFile) {
$this->files->requireOnce($migrationFile);
}
}
if (class_exists($className = $this->getClassName($name))) {
throw new InvalidArgumentException("A {$className} class already exists.");
}
}
/**
* Get the migration stub file.
*
* @param string|null $table
* @param bool $create
* @return string
*/
protected function getStub($table, $create)
{
if (is_null($table)) {
$stub = $this->files->exists($customPath = $this->customStubPath.'/migration.stub')
? $customPath
: $this->stubPath().'/migration.stub';
} elseif ($create) {
$stub = $this->files->exists($customPath = $this->customStubPath.'/migration.create.stub')View on GitHub (pinned to e0f6eb3518)