Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

fbc's avatar
Level 2

Logic Exception

When I run my migrations i get an error for an entry in my routes, but I can't quite figure out what is wrong. Everything continues to work as it should.


   LogicException 

  Unable to prepare route [api/user] for serialization. Uses Closure.

  at vendor/laravel/framework/src/Illuminate/Routing/Route.php:1150
    1146|      */
    1147|     public function prepareForSerialization()
    1148|     {
    1149|         if ($this->action['uses'] instanceof Closure) {
  > 1150|             throw new LogicException("Unable to prepare route [{$this->uri}] for serialization. Uses Closure.");
    1151|         }
    1152| 
    1153|         $this->compileRoute();
    1154| 

      +15 vendor frames 
  16  artisan:37
      Illuminate\Foundation\Console\Kernel::handle()

it seems the offending value is this:

Auth::routes(['register' => false]);

0 likes
9 replies
Sinnbeck's avatar

Are you sure this happens when migrating and not when caching routes? That is a basic "cache routes" error.

Check your routes again. Most likely you have a route that has a closure somewhere

Something like.

Route::get('/', function() {
    return view('home');
});
Niush's avatar

In the api.php the route for api/user is probably handled in Closure (Instead of Controller)

So, the artisan command php artisan route:cache cannot serialize the closure

Since this feature uses PHP serialization, you may only cache the routes for applications that exclusively use controller based routes. PHP is not able to serialize Closures. https://laravel.com/docs/7.x/deployment#optimizing-route-loading

Now, when running migration this should not be occurring unless route:cache is ran. Probably an alias command was created?

This might be fixed in Laravel 8 (Not Sure though)

@sinnbeck Is it fixed in Laravel 8 ? Any idea. The new documentation does not include this warning.

fbc's avatar
Level 2

My routes look like this:

<?php
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/

// Auth::routes();
Auth::routes(['register' => false]);

Route::get('/', 'HomeController@index')->name('home');
Route::get('/home', 'HomeController@index')->name('home');

//Material Related Routes
Route::resource('material/profile', 'material\ProfileController');
Route::resource('material/vbarrierprod', 'material\VbarrierProdController');
Route::resource('material/insulationprod', 'material\InsulationProdController');
Route::resource('material/insupinprod', 'material\InsuPinProdController');
Route::resource('material/primerprod', 'material\PrimerprodController');
Route::resource('material/subgirtprod', 'material\SubgirtProdController');
Route::resource('setup/contractor', 'setup\ContractorController');
Route::resource('setup/vendor', 'setup\VendorController');

// Adding Jobs
Route::get('estimate/{estimate}/recalc', 'estimate\EstimateController@recalc')
    ->name('estimate.recalc');
Route::resource('estimate', 'estimate\EstimateController');
//For making Predefined Wall Types.
Route::resource('estimate.walltype', 'estimate\walltype\WallTypeController');
//For adding insulation to Predefined Wall Types.
Route::resource('estimate.walltype.insulation', 'estimate\walltype\WalltypeInsulationController');
//For adding vbarrier to Predefined Wall Types.
Route::resource('estimate.walltype.vbarrier', 'estimate\walltype\WalltypeVbarrierController');
//For adding subgirt to Predefined Wall Types.
Route::resource('estimate.walltype.subgirt', 'estimate\walltype\WalltypeSubgirtController');
//For adding sections to jobs
Route::get('estimate/{estimate}/section/{section}/recalc', 'estimate\SectionController@recalc')
    ->name('section.recalc');
Route::resource('estimate.section', 'estimate\SectionController');
//For adding cladding to sections
Route::get(
    'estimate/{estimate}/section/{section}/cladding/createfromwalltype',
    'estimate\CladdingController@createFromWalltype'
)
    ->name('estimate.section.cladding.createfromwalltype');
Route::post(
    'estimate/{estimate}/section/{section}/cladding/storefromwalltype',
    'estimate\CladdingController@storeFromWalltype'
)
    ->name('estimate.section.cladding.storefromwalltype');
Route::resource('estimate.section.cladding', 'estimate\CladdingController');
//For adding vapor barriers to cladding
Route::resource('estimate.section.cladding.vbarrier', 'estimate\VbarrierController');
//For adding insulation to cladding
Route::resource('estimate.section.cladding.insulation', 'estimate\InsulationController');
//For adding subgirt to cladding
Route::resource('estimate.section.cladding.subgirt', 'estimate\SubgirtController');
//This is more like a pivot table
Route::resource('estimate.estimatecontractor', 'estimate\EstimateContractorController');
Route::resource('estimate.detail', 'estimate\DetailController'); //Adding Details to Job

Route::get('estimate/{estimate}/detail/{detail}/trim/add-custom', 'estimate\TrimController@createcustom')
    ->name('trim.createcustom'); //Adding Custom Trim
Route::resource('estimate.detail.trim', 'estimate\TrimController'); //Adding trim to Details

Route::get('/estimate/getpdf/{estimate}', 'estimate\EstimateController@pdf')
    ->name('create.estimate-pdf');
Route::get('/estimate/getprintview/{estimate}', 'estimate\EstimateController@printview')
    ->name('estimate.printview');

Route::post('/estimate/uploadafile', 'estimate\EstimateController@uploadafile')
    ->name('estimate.uploadafile');
Route::delete('/estimate/deleteafile/{token}', 'estimate\EstimateController@deleteafile')
    ->name('estimate.deleteafile');

Route::post('/estimate/detail/uploadafile', 'estimate\DetailController@uploadanimage')
    ->name('detail.uploadanimage');
Route::delete('/estimate/detail/deleteafile/{token}', 'estimate\DetailController@deleteanimage')
    ->name('detail.deleteanimage');

Route::resource('/estimate/equipment', 'estimate\EquipmentController');
Route::get('/estimate/equipment/create-equipment/{token}', 'estimate\EquipmentController@createequip')
    ->name('equipment.createequip');

Route::resource('/estimate/freight', 'estimate\FreightController');
Route::get('/estimate/freight/create-freight/{token}', 'estimate\FreightController@createfreight')
    ->name('freight.createfreight');



//Project Related
Route::get('project/{project}/filemanager', 'project\ProjectController@filemanager')
    ->name('project.filemanager'); // filemanager
Route::resource('project', 'project\ProjectController'); // Project Crud

//Budget Related
Route::resource('project.budget', 'project\BudgetController'); // Budget Crud

// Bill related
Route::post('project.bill.uploadafile', 'project\bill\BillController@uploadafile')
    ->name('bill.uploadafile');
Route::delete('project.bill.deleteafile/{token}', 'project\bill\BillController@deleteafile')
    ->name('bill.deleteafile');
Route::get('project/{project}/bill/createpb', 'project\bill\BillController@createpb')
    ->name('project.bill.createpb');
Route::get('project/{project}/bill/{bill}/approve', 'project\bill\BillController@approve')
    ->name('project.bill.approve');
Route::get('project/{project}/bill/{bill}/unapprove', 'project\bill\BillController@unapprove')
    ->name('project.bill.unapprove');
Route::get('project/{project}/bill/{bill}/createqbinvoice', 'project\bill\BillController@createqbinvoice')
    ->name('project.bill.createqbinvoice');
Route::resource('project.bill', 'project\bill\BillController'); // Bill Crud
Route::resource('project.bill.billitem', 'project\bill\BillItemController'); // BillItem Crud
Route::resource('project.bill.bcoitem', 'project\bill\BCOItemController'); // BCOItem Crud
Route::resource('project.bill.billrev', 'project\bill\BillRevController'); // BillRev Crud

//Change Order Related
Route::post(
    'project.changeorder.uploadafile',
    'project\changeorder\ChangeOrderController@uploadafile'
)
    ->name('project.changeorder.uploadafile');
Route::delete(
    'project.changeorder.deleteafile/{token}',
    'project\changeorder\ChangeOrderController@deleteafile'
)
    ->name('project.changeorder.deleteafile');
Route::get(
    'project/{project}/changeorder/{changeorder}/approve',
    'project\changeorder\ChangeOrderController@approve'
)
    ->name('project.changeorder.approve');
Route::get(
    'project/{project}/changeorder/{changeorder}/unapprove',
    'project\changeorder\ChangeOrderController@unapprove'
)
    ->name('project.changeorder.unapprove');
Route::resource('project.changeorder', 'project\changeorder\ChangeOrderController'); // ChangeOrder Crud
Route::resource('project.changeorder.coitem', 'project\changeorder\CoItemController'); // Change Order line Item Crud
Route::resource('project.changeorder.corev', 'project\changeorder\CoRevController'); // BillRev Crud

/* Purchase Order Retlated */
Route::post(
    'project.purchaseorder.uploadafile',
    'project\purchaseorder\PurchaseOrderController@uploadafile'
)
    ->name('project.purchaseorder.uploadafile');
Route::delete(
    'project.purchaseorder.deleteafile/{token}',
    'project\purchaseorder\PurchaseOrderController@deleteafile'
)
    ->name('project.purchaseorder.deleteafile');
Route::get(
    'project/{project}/purchaseorder/{purchaseorder}/approve',
    'project\purchaseorder\PurchaseOrderController@approve'
)
    ->name('project.purchaseorder.approve');
Route::get(
    'project/{project}/purchaseorder/{purchaseorder}/unapprove',
    'project\purchaseorder\PurchaseOrderController@unapprove'
)
    ->name('project.purchaseorder.unapprove');
Route::resource('project.purchaseorder', 'project\purchaseorder\PurchaseOrderController'); /* PurchaseOrder Crud */
Route::resource('project.purchaseorder.porev', 'project\purchaseorder\PoRevController'); /* PoRev Crud */
Route::resource('project.purchaseorder.poitem', 'project\purchaseorder\PoItemController'); /* PO line Item Crud */

/* RFI related */
Route::resource('project.rfi', 'project\rfi\RFIController'); /* RFI Crud */



/* Company Profile and Contact */
Route::resource('company', 'contact\CompanyController'); // Company Crud
Route::resource('company.contact', 'contact\ContactController'); // Contact Crud

Route::group(['prefix' => 'filemanager', 'middleware' => ['web', 'auth']], function () {
    \UniSharp\LaravelFilemanager\Lfm::routes();
});


Route::get('generator_builder', '\InfyOm\GeneratorBuilder\Controllers\GeneratorBuilderController@builder')
    ->name('io_generator_builder');

Route::get('field_template', '\InfyOm\GeneratorBuilder\Controllers\GeneratorBuilderController@fieldTemplate')
    ->name('io_field_template');

Route::get(
    'relation_field_template',
    '\InfyOm\GeneratorBuilder\Controllers\GeneratorBuilderController@relationFieldTemplate'
)
    ->name('io_relation_field_template');

Route::post('generator_builder/generate', '\InfyOm\GeneratorBuilder\Controllers\GeneratorBuilderController@generate')
    ->name('io_generator_builder_generate');

Route::post('generator_builder/rollback', '\InfyOm\GeneratorBuilder\Controllers\GeneratorBuilderController@rollback')
    ->name('io_generator_builder_rollback');

Route::post(
    'generator_builder/generate-from-file',
    '\InfyOm\GeneratorBuilder\Controllers\GeneratorBuilderController@generateFromFile'
)->name('io_generator_builder_generate_from_file');

fbc's avatar
Level 2

Yes, I think it's happening when caching routes.. It's part of my update script.

fbc's avatar
Level 2

Yeah! I think that is where it's at:

Route::middleware('auth:api')->get('/user', function (Request $request) {
    return $request->user();
});
Sinnbeck's avatar
Sinnbeck
Best Answer
Level 102

Bingo. Move that to a controller or delete it :)

fbc's avatar
Level 2

Yeh, I don't think I'm using any api requests for anything at the moment.. so I'll probably delete it.

Please or to participate in this conversation.