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

lara28580's avatar

Livewire 3 upgrade "livewire/update" 404 Error

I upgraded my app to livewire 3 and now I am getting an error after I call a method in a livewire component. I get the following error livewire.js?id=af0b760a:536 POST http://localhost/livewire/update 404 (Not Found)

I tried already https://github.com/mcamara/laravel-localization/issues/880 but without success.

Code which gets called and executed

public function destroy(QrCode $qrCode)
    {
        $qrCode->delete();

        $this->closeModal();

        $this->dispatch('success-message', ['message' => '']);

        $this->dispatch('refreshComponent');
    }

Maybe someone can help please

0 likes
63 replies
tisuchi's avatar

@SmokeTM Can you try this?

php artisan livewire:publish --assets

You may need to clear your browser caches / hard refresh!

1 like
lara28580's avatar

Maybe you need the whole component class. I am using the wire-elements package maybe it is conflicting with that?

<?php

namespace App\Livewire\Admin\User;

use App\Models\User;
use LivewireUI\Modal\ModalComponent;

class DeleteUser extends ModalComponent
{
    public User $user;

    /**
     * Remove the specified resource from storage.
     *
     * @return \Illuminate\Http\Response
     */
    public function destroy(User $user)
    {
        $user->delete();

        $this->closeModal();

        $this->dispatch('success-message', ['message' => '']);

        $this->dispatch('refreshComponent');
    }

    public function render()
    {
        return view('livewire.admin.user.delete-user');
    }
}
lara28580's avatar

I also tried to add the following to my web.php without success.

Livewire::setUpdateRoute(function ($handle) {
    return Route::post('/livewire/update', $handle);
});

Someone has another idea what I can do?

Snapey's avatar

is your project in localhost or in a folder of localhost? What do your urls look like for regular pages?

1 like
lara28580's avatar

@Snapey Thnaks for you fast reply. My project is in localhost, yes.

Here is an example page

http://localhost/invoices
1 like
Snapey's avatar

you don't have a livewire route in your routes files?

1 like
lara28580's avatar

@Snapey Sry but what do you mean with that? What I tried is adding the following to web.php.

Livewire::setUpdateRoute(function ($handle) {
    return Route::post('/livewire/update', $handle);
});
Snapey's avatar

in your component you have public property of user model. But you delete this model so when the component is re-hydrated the model is not found , possibly leading to 404 for model not found

in your destroy method you should set $this->user to null ?

1 like
lara28580's avatar

@Snapey If I try that

public function destroy(User $user)
    {
        $user->delete();

        $this->user = null;

        $this->closeModal();

        $this->dispatch('success-message', ['message' => 'Der Benutzer wurde erfolgreich gelöscht.']);

        $this->dispatch('refreshComponent');
    }

I get the following error

Cannot assign null to property App\Livewire\Admin\User\DeleteUser::$user of type App\Models\User
lara28580's avatar

The strange thing the same code worked with livewire 2 perfectly.

lara28580's avatar

@Snapey No get the same error. livewire.js?id=af0b760a:536 POST http://localhost/livewire/update 404 (Not Found)

Snapey's avatar

is this id the component with the delete or some parent where the list of users is shown?

If there is a parent list you need to tell it that this user has been deleted so that it does not try to list it

1 like
lara28580's avatar

@Snapey The is a parent where the list of users is shown. How to tell that? Its a modal which is called in the list of users "wire-elements/modal" package.

lara28580's avatar

This is my parent class

class Users extends Component
{
    use WithPagination;

    public $search;

    protected $queryString = ['search'];

    protected $listeners = ['refreshComponent' => '$refresh'];

    public function updatingSearch()
    {
        $this->resetPage();
    }

    public function render()
    {
        $users = User::where(function ($query) {
            $query->where('name', 'like', '%'.$this->search.'%')
                ->orWhere('email', 'like', '%'.$this->search.'%');
        })->orderBy('created_at', 'DESC')->paginate(20);

        return view('livewire.admin.user.users', ['users' => $users]);
    }
}
Snapey's avatar

@SmokeTM does not seem to be a problem in the parent since the list of users is gathered in render

So to find out if this IS an issue with deleting, you could temporarily just modify the model and see if that works ok

public function destroy(User $user)
    {
        $user->name = $user->name . 'D';

        $user->save();

       // $this->user = null;

        $this->closeModal();

        $this->dispatch('success-message', ['message' => 'Der Benutzer wurde erfolgreich gelöscht.']);

        $this->dispatch('refreshComponent');
    }

This justs adds a D to the name each time you use it

Snapey's avatar

@SmokeTM good so there is no issue with routing to livewire/update, the issue is coming from deleting the object

1 like
lara28580's avatar

@Snapey Ok thanks for your help, but what does that mean? How should I delete the object then?

Snapey's avatar

@SmokeTM im trying to work out what it means....

Why do you have public $user? Your destroy method is not using it? Destroy uses route model binding. Do you have other methods in this component that also rely on RMB ?

You could switch destroy over to resolving the model itself?

public function destroy($id)
    {

        $user = User::find($id);
        $user->delete();

        $this->closeModal();

        $this->dispatch('success-message', ['message' => 'Der Benutzer wurde erfolgreich gelöscht.']);

        $this->dispatch('refreshComponent');
    }
Snapey's avatar

@SmokeTM so do you have other functions that try to use the now deleted user model? What about render()?

1 like
lara28580's avatar

@Snapey No, maybe it is the parent component trying to access the deleted user?

lara28580's avatar

@Snapey

<div>
    <x-livewire.success />
    <div class="sm:flex sm:items-center">
        <div class="sm:flex-auto">
            <h1 class="text-xl font-semibold text-slate-900">Benutzer</h1>
        </div>
        <div class="mt-4 sm:mt-0 sm:ml-16 sm:flex-none">
            <x-primary-link href="{{ route('admin.users.create') }}">
                Neuer Benutzer
            </x-primary-link>
        </div>
    </div>
    <div class="my-5 max-w-sm">
        <x-admin.search placeholder="Suche nach Name oder E-Mail" />
    </div>
    <div class="flex flex-col">
        @if (!$users->isEmpty())
            <div class="-my-2 -mx-4 overflow-x-auto sm:-mx-6 lg:-mx-8">
                <div class="inline-block min-w-full py-2 align-middle md:px-6 lg:px-8">
                    <div class="overflow-hidden shadow ring-1 ring-black ring-opacity-5 md:rounded-lg">
                        <table class="min-w-full divide-y divide-gray-300">
                            <thead class="bg-slate-50">
                                <tr>
                                    <th scope="col"
                                        class="px-3 py-3.5 text-left text-sm font-semibold text-slate-900">
                                        Name</th>
                                    <th scope="col"
                                        class="px-3 py-3.5 text-left text-sm font-semibold text-slate-900">
                                        Email
                                    </th>

                                    <th scope="col"
                                        class="px-3 py-3.5 text-left text-sm font-semibold text-slate-900">
                                        Erstellt am
                                    </th>

                                    <th scope="col"
                                        class="px-3 py-3.5 text-left text-sm font-semibold text-slate-900">
                                        Type
                                    </th>

                                    <th scope="col" class="relative py-3.5 pl-3 pr-4 sm:pr-6">
                                        <span class="sr-only">Aktionen</span>
                                    </th>
                                </tr>
                            </thead>
                            <tbody class="divide-y divide-gray-200 bg-white">
                                @foreach ($users as $user)
                                    <tr>
                                        <td class="whitespace-nowrap px-3 py-4 text-sm text-slate-500">
                                            <div class="text-slate-900">{{ $user->name }}</div>
                                        </td>
                                        <td class="whitespace-nowrap px-3 py-4 text-sm text-slate-500">
                                            <div class="text-slate-900">{{ $user->email }}</div>
                                        </td>
                                        <td class="whitespace-nowrap px-3 py-4 text-sm text-slate-500">
                                            <div class="text-slate-900">{{ $user->created_at->format('d.m.Y') }}
                                            </div>
                                        </td>
                                        <td class="whitespace-nowrap px-3 py-4 text-sm text-slate-500">
                                            @if ($user->isAdmin())
                                                <x-admin.badge />
                                            @else
                                                <x-user.badge />
                                            @endif
                                        </td>
                                        <td
                                            class="relative whitespace-nowrap py-4 pl-3 pr-4 text-right text-sm font-medium sm:pr-6">
                                            <x-primary-table-link href="{{ route('admin.users.edit', $user) }}">
                                                Editieren
                                                <span class="sr-only"></span>
                                            </x-primary-table-link>

                                            <x-table-delete-button :model="$user" type="user" name="user">
                                                Löschen
                                            </x-table-delete-button>
                                        </td>
                                    </tr>
                                @endforeach
                            </tbody>
                        </table>
                    </div>
                </div>
            </div>
            <div class="px-4 py-5 sm:px-6">
                {{ $users->links() }}
            </div>
        @elseif(!empty($search))
            <p class="mt-2 text-sm">Es wurden keine Benutzer mit <strong>{{ $search }}</strong> gefunden.</p>
        @else
            <p class="mt-2 text-sm">Es sind keine Benutzer vorhanden.</p>
        @endif
    </div>
</div>

table-delete-button

<button
    wire:click="$dispatch('openModal', { component: 'admin.{{ $type }}.delete-{{ $type }}' ,
    arguments: { {{ $name }}: '{{ $model->id }}' }})"
    {{ $attributes->merge(['type' => 'button', 'class' => 'ml-3 px-4 py-2 rounded bg-red-700 text-white hover:bg-red-900 hover:text-accent whitespace-nowrap']) }}>
    {{ $slot }}
</button>
lara28580's avatar

I think it has something to do with the mcamara/laravel-localization package I am using

lara28580's avatar

It was a big mistake to upgrade from livewire 2 to 3. Everything worked perfectly.

Snapey's avatar

A couple of things.

1.Ensure you always use wire:key inside foreach loops

                                @foreach ($users as $user)
                                    <tr wire:key="{{ $user->id }}">

2.What code is behind this function? $user->isAdmin()

1 like
lara28580's avatar

@Snapey added the wire:key thanks for the tip thought that is only required if I use livewire components in loops.

isAdmin function

/**
     * Check if user is admin
     */
    public function isAdmin(): bool
    {
        return $this->type === self::ADMIN;
    }
lara28580's avatar

If I switch language to es for example then I get http://localhost/es/livewire/update 404 (Not Found)

lara28580's avatar

@Snapey Think thats the same because default local is not in url. So this is why url without locale is also producing http://localhost/livewire/update 404 (Not Found)

lara28580's avatar

@Snapey No more ideas? I'm a bit desperate because I really need to solve this

Snapey's avatar

@SmokeTM we have already established that without deleting the model all works ok (in default locale)

Any problems when switching to a different locale are a different problem.

I've run out of ideas based on code I can see.

The only thing not followed up was to check if the error is from the modal or from the list, which you can check with the wire id.

1 like
lara28580's avatar

@Snapey The only thing not followed up was to check if the error is from the modal or from the list, which you can check with the wire id. You can explain in detail please?

Snapey's avatar

@SmokeTM in your original question livewire.js?id=af0b760a:536

I was wondering if the code shown here (and this probably changes) relates to the wire Id you can see with the element inspector

1 like
lara28580's avatar

@Snapey livewire.js?id=af0b760a this stays the same what I can see in my inspector

MaquinaTech's avatar

Going from Livewire 2 to 3 has caused many problems for many developers, one of the most serious is the asynchronous execution of processes and calls, in livewire 2 you could make several dispatch or calls to the DB and they were executed asynchronously and not according to your choice but now it is not possible since all the calls are grouped in the order that livewire wants, could it be that the order in which the dispatches are executed is incorrect? I think you can see in the browser console under network the order of applying Livewire queries

lara28580's avatar

@MaquinaTech Thanks for your answer. What I can see under the network tap is 3 update request were made. 2 request with status code 200 and 1 with 404.

MaquinaTech's avatar

@SmokeTM And you can't see which is which? It would be interesting to know which dispatch is the one that is failing

MaquinaTech's avatar

@SmokeTM Could you show me what is executed in that function? It seems to be running after refresh and that's why it can't find it

lara28580's avatar

@MaquinaTech

public function closeModal(): void
    {
        $this->dispatch('closeModal', force: $this->forceClose, skipPreviousModals: $this->skipModals, destroySkipped: $this->destroySkipped);
    }
MaquinaTech's avatar

@SmokeTM Try putting the last two dispatches (success and refresh messages) inside closeModal to see if it solves (it's just to prove that it is a request order error then you can give it a more professional solution)

MaquinaTech's avatar

@SmokeTM I see that in the closeModal function you make another dispatch to closeModal, what is the final function of the call?

1 like
lara28580's avatar

@MaquinaTech Don't know where to find this function. The 404 Status code is appearing on modal close no matter how it is closed.

MaquinaTech's avatar

@SmokeTM You could look for the closeModal listener in your project because if the error is in the closeModal dispatch and the error is 404, it means that it does not find the component with the listener and the function, it may be because it has been previously deleted due to the bad order of update requests that performs livewire 3

1 like
lara28580's avatar

@MaquinaTech Somehow if I do not delete the user and call closeModal it works perfectly. Maybe livewire expects the model to exist on closeModal(). Where to find that listener?

Snapey's avatar

@SmokeTM show your complete modal class.

Do you still have public User $user ?

1 like
lara28580's avatar

@Snapey

<?php

namespace App\Livewire\Admin\User;

use App\Models\User;
use LivewireUI\Modal\ModalComponent;

class DeleteUser extends ModalComponent
{
    public ?User $user;

    /**
     * Remove the specified resource from storage.
     *
     * @return \Illuminate\Http\Response
     */
    public function destroy(User $user)
    {
        $this->closeModal();

        $this->dispatch('success-message', message: '');

        $this->dispatch('refreshComponent');
    }

    public function render()
    {
        return view('livewire.admin.user.delete-user');
    }
}

Sure.

lara28580's avatar

@Snapey Or what do you mean with that? I have to pass the id of the user to the modal to than be able to destroy the same.

Snapey's avatar

@SmokeTM but the point is you are not using $this->user in the destroy method, you are passing it to the function directly.

Remember one of the first things I suggested was to remove public $user ?

1 like
lara28580's avatar
lara28580
OP
Best Answer
Level 10

Ok got it solved! It was the none existing mount method.....

  public $user;

    public function mount(User $user)
    {
        $this->user = $user;
    }

    /**
     * Remove the specified resource from storage.
     *
     * @return \Illuminate\Http\Response
     */
    public function destroy(User $user)
    {
        $user->delete();

        $this->closeModal();

        $this->dispatch('success-message', message: '');

        $this->dispatch('refreshComponent');
    }

    public function render()
    {
        return view('livewire.admin.user.delete-user');
    }

Please or to participate in this conversation.