The problem: A Livewire component throws a "Snapshot Missing" error whenever a user's session expires mid-interaction and they trigger any component action.
Environment: Laravel 11, Livewire 3.x, PHP 8.3, Redis/File session driver
The Error
Livewire\Exceptions\CorruptComponentPayloadException: Snapshot missing on Livewire component
with id: "a8f3c21"
POST http://app.test/livewire/update 419 (unknown status)
Why It Happens
Livewire stores a "snapshot" of each component's state — its properties, checksum, and metadata — inside the request payload sent back to the server on every interaction. That snapshot is tied to the session that was active when the component was first rendered.
When the session expires (timeout, driver eviction, or the session cookie getting cleared), the server no longer recognizes the component's original context. Livewire can't validate the checksum against a session that no longer exists, so instead of a clean 419 redirect, it throws this corrupt-payload exception — because the snapshot itself references session data that's now gone.
This is especially common on pages left open in a browser tab for longer than session.lifetime, or on sites using a short session timeout for security reasons (banking-style admin panels, for example).
The Fix
You can't stop sessions from expiring, but you can catch the expiration gracefully and redirect the user instead of showing a raw exception. Livewire ships a built-in event for exactly this — hook into it on the frontend:
<script>
document.addEventListener('livewire:init', () => {
Livewire.hook('request', ({ fail }) => {
fail(({ status, preventDefault }) => {
if (status === 419) {
alert('Your session expired. The page will reload.');
window.location.reload();
preventDefault();
}
});
});
});
</script>
Then extend your session lifetime for pages where users tend to sit idle (form-heavy dashboards, long survey pages), rather than fighting the default:
- SESSION_LIFETIME=120
+ SESSION_LIFETIME=480
If you're on Redis or another external session driver, also confirm the driver's own TTL isn't shorter than SESSION_LIFETIME — a mismatched Redis key expiry will cause this exact bug even with the config above set correctly.
Step-by-Step
- Add the
livewire:inithook shown above to your main layout file (not per-component). - Set
preventDefault()inside the 419 check so Livewire doesn't also throw its default error to the console. - Decide on a real session lifetime for your app's use case and update
SESSION_LIFETIMEin.env. - If using Redis, run
redis-cli CONFIG GET maxmemory-policyand confirm keys aren't being evicted early under memory pressure. - Clear config cache after any
.envchange:php artisan config:clear. - Test by manually expiring a session (delete the session cookie in DevTools) and triggering a Livewire action to confirm the reload prompt appears instead of the raw exception.
Edge case: If your app uses wire:poll for auto-refreshing components, a background tab can hit this error repeatedly while the user isn't even looking at the screen, spamming your error logs with false positives. Consider pausing polling with wire:poll.visible so it only runs while the tab is active — this cuts down noise significantly on dashboards.
Running into a different variant of this error? Get in touch via the Contact page and I'll help you trace it.