86

I do not know why this error occurs when I execute the migrations as I do not have repeated classes.

Migrations:

2014_10_12_100000_create_password_resets_table.php
2019_01_18_020910_create_roles_table.php
2019_01_18_025535_create_members_table.php
2019_01_18_025536_create_users_table.php
2019_01_18_183649_create_projects_table.php
2019_01_18_184249_create_member_project_table.php
2019_01_18_184719_create_sprints_table.php
2019_01_18_185218_create_tasks_table.php
2019_01_21_033045_add_shortname_to_project.php

Error:

PHP Fatal error:  Cannot declare class CreateRolesTable, because the name is already in use in
oyectos\database\migrations\2019_01_18_020910_create_roles_table.php on line 33

In 2019_01_18_020910_create_roles_table.php line 33:

  Cannot declare class CreateRolesTable, because the name is already in use

Class:

class CreateRolesTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('roles', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name',128)->unique();
            $table->string('description');
            $table->boolean('system');
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('roles');
    }
}
miken32
  • 42,008
  • 16
  • 111
  • 154
Federico Fia Sare
  • 1,166
  • 2
  • 8
  • 15

11 Answers11

141

As well as other answers given, this error can also happen if the migration filename is not a snake-case version of the class name.

So a migration file 2019_01_18_020910_create_roles_table.php must contain the class CreateRolesTable. If it contains the class CreateRoleTable, with a missing s, then the "Cannot declare X..." error is thrown. I've found this on Laravel 8, and may apply to earlier versions.

It appears to happen because Laravel loads the migration file multiple times when the filename is misspelled, and the second time loading is when the exception is throw.

Jason
  • 4,411
  • 7
  • 40
  • 53
  • 3
    The date and time needs to be formatted correctly too: `yyyy_mm_dd_hhmmss_` – MarijnK May 25 '21 at 09:20
  • 4
    Since the migration files are not namespaced, they don't use PSR-4 auto-loading. So Laravel just `includes` the files and makes a guess at what class was in it, based on the filename. When the class inside the migration does not follow the pattern, I can see how that is an edge case that could go wrong. It could be handled better, but it's been like this for like forever, with no rush for a fix. I think the bug is that Laravel does not complain immediately it does not find the class it expects when including the migration file. – Jason May 30 '21 at 21:30
  • 2
    This solved my problem. But I wanted to stress out that the date and time has to be formatted correctly. At first, it didn't worked for me because I renamed the file from CreateRoleTable.php to create_role_table.php. But when I added the date and time, it worked yyyy_mm_dd_hhmmss_create_role_table.php – Hassan Al-Jeshi Dec 10 '21 at 16:22
57

First Solution :

It seems like you have 2 migrations done at different time with essentially same name.

for example : 2019_01_18_020910_create_roles_table.php

and 2019_01_16_020910_create_roles_table.php

Laravel will convert this filename eliminating the date signature and Camel Casing the remaining text.

So both of these migration will have class CreateRolesTable even if the time signatures are different. Check if your migrations directory have such 2 files.

To check this run this from terminal in project root : grep -ri 'createrolestable' database/migrations

Second Solution :

Sometimes composer's internal class autoloading causes this issue. Do following to check if it resolves :

run composer install

Third Solution :

This is likely to be invalid but a same file should not have same class declaration 2 files by mistake.

Fourth Solution :

There might be a package you have installed which has a migration with same class name. To find run grep -ril 'createrolestable' vendor

If it shows any file then thats what causing 2 classes to have same names.

You can create a new one php artisan make:migration create_roles_table_custom . and then copy what you have in current migration to the new one and delete the existing one(not from package but the one you have created).

This will create a class CreateRolesTableCustom which is different than what the package already has.

Mihir Bhende
  • 8,677
  • 1
  • 30
  • 37
  • $ grep -ri 'createrolestable' database/migrations database/migrations/2019_01_18_020910_create_roles_table.php:class CreateRolesTable extends Migration – Federico Fia Sare Feb 19 '19 at 12:21
  • Then your migrations are good. can you do the second option and run `composer install` ? – Mihir Bhende Feb 19 '19 at 12:32
  • yes, try the three alternatives and I could not solve it. I recently had a problem that all the migrations were erased so I had to recreate them again, there is some cache or something in which the references are stored or something like that. – Federico Fia Sare Feb 19 '19 at 12:39
  • Can you do `composer dump-autoload` and check for the output. Is it showing any warning it yellow about this class name. Also check for any whitespaces at end of the migration file? – Mihir Bhende Feb 19 '19 at 12:48
  • composer dump-autoload Generating optimized autoload files> Illuminate\Foundation\ComposerScripts::postAutoloadDump > @php artisan package:discover Discovered Package: barryvdh/laravel-debugbar Discovered Package: brian2694/laravel-toastr Discovered Package: fideloper/proxy Discovered Package: laracasts/generators Discovered Package: laravel/tinker Discovered Package: nesbot/carbon Package manifest generated successfully. Generated optimized autoload files containing 3512 classes. There are no warnings – Federico Fia Sare Feb 19 '19 at 13:08
  • 1
    Thats strange, Can do you : `grep -ril 'createrolestable' vendor` if you have installed any package having this class name? – Mihir Bhende Feb 19 '19 at 13:10
  • $ grep -ril 'createrolestable' vendor vendor/uzzal/acl/src/database/migrations/2015_12_22_103904_create_roles_table.php. only this file appears – Federico Fia Sare Feb 19 '19 at 13:17
  • There you go :) You already have a migration in a package with the same name. You can delete your own migration, create a new one `php artisan make:migration create_roles_table_custom` . and then copy what you have in current migration to the new one. This will create a class `CreateRolesTableCustom` which is different than what the package already has – Mihir Bhende Feb 19 '19 at 13:19
  • Thank you!!! I do not know why it does not appear in the search engine but I went to the route. Can I delete that plugin migration? because it generates conflict because I want to create the table twice roles – Federico Fia Sare Feb 19 '19 at 13:24
  • I have updated my answer. Deleting the plugin migration is no a good idea, you can either remove that package or do what I mentioned. Do you already have a `roles` table? – Mihir Bhende Feb 19 '19 at 13:25
  • Yes, I use my role table, the plugin migrations do not use them. – Federico Fia Sare Feb 19 '19 at 13:58
  • you will get this error also if the name of the class inside the file doesn't match the file name for example if ( the filename is "2019_01_18_020910_create_roles_table.php" and the class is "CreateRoleTable" as you can see the word role in the file name has 's' at the end but the class name doesn't) – zoubair Omar May 20 '21 at 15:39
  • Hello @MihirBhende , Yes I do have multiple migrations with the same name. Should I just rename the migration file and class name? Is that acceptable? – Akshay K Nair Sep 18 '21 at 11:20
  • Yes that it acceptable. But if you are worried about the name updates causing ani issue, I would just copy the migration's up and down method bodies and create a new migration command with desired name. And then paste it in there. Then delete the old one – Mihir Bhende Sep 19 '21 at 19:31
11

If you are using Laravel 8 or above, you can use Anonymous Migration to avoid the conflict with Class name.

Below is how you to declare an Anonymous Migration. Do not forget the semicolon at the end.

return new class extends Migration
{
    //
};

More from the Docs.

ascsoftw
  • 3,466
  • 2
  • 15
  • 23
  • It's unfortunate that this is the only to get it to work in v8, AND IT'S NOT EXPLICITLY STATED. The code was refactored specifically to prevent regular classes from being used as migrators, no thanks to the double `require`. The way it's set up, it simply can't work otherwise – I Want Answers Mar 25 '22 at 21:55
8

Becareful of migration file name.

For me, migration file name was:

2021-10-13_000000_create_examples_table

But correct was :

2021_10_13_000000_create_examples_table

LOL

Mojtaba Michael
  • 340
  • 4
  • 11
2

In my case, i had my own package, which had migraration and it wasn't named properly. I named it without date like this: create_orders_table. I changed it to 2021_08_03_000000_create_orders_table and it helped.

2

I ran into this (misleading) error and it turned out I accidently omitted the word Create from the migration class name.

Error: Cannot declare class FooTable, because the name is already in use

Incorrect: class FooTable extends Migration

Correct: class CreateFooTable extends Migration

Tyler
  • 161
  • 1
  • 11
  • I had the same issue in my custom package migration where I prepended the class name so it looked like CmsCreateFailedLoginAttemptsTable But needed to be CreateCmsFailedLoginAttemptsTable – Derek Buntin Sep 24 '21 at 00:46
1

For me, it was a problem with Laravel Sanctum (now built into Laravel 8). I had generated migrations via a package and somehow ended up with something in vendor\laravel\sanctum\database\migrations.

I ran php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider" to persist it to standard migrations.

See here for details.

Vael Victus
  • 3,966
  • 7
  • 34
  • 55
0

I had this problem. I used composer dump-autoload and it solved the problem.

0

Even if you don't have any such files with same Class name and you are still facing the same problem then try

composer dump-autoload
Jay Momaya
  • 1,831
  • 19
  • 32
0

This can be caused by a number of things. Follow these steps to resolve the issue. First run this command in terminal

php artisan optimize:clear

composer dump-autoload

If those don't resolve the issue, then you have renamed a migration file that was published from Laravel Cashier. To resolve it, do the following:

Rename the migration file. Something like 2019_01_18_020910_create_roles_table can be renamed to 2019_01_18_020910_create_role_table

Rename the class. Something like CreateRolesTable can be renamed to CreateRoleTable

Junior
  • 1,007
  • 4
  • 16
  • 26
0

in my case, it's throwing the error because I changed the time of migration file which are added by laravel cashier, my time sequence is correct but it's still throwing name issue.

Then I revert the time back to the original migration time and the problem is solved.

Hadayat Niazi
  • 1,991
  • 3
  • 16
  • 28