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

  1. Choose a more specific migration name (e.g. add_status_to_users_table) so the derived class name is unique.
  2. Delete or rename the pre-existing migration file that owns the colliding class name, then re-run.
  3. 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

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


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)