14

I am getting the following error and am a bit lost on it:

Livewire encountered corrupt data when trying to hydrate the … component. Ensure that the [name, id, data] of the Livewire component wasn’t tampered with between requests

Situation is as follows: Livewire 2.x, Laravel 7.x, Component Controller fetches data from 3 MySQL Stored Procedures and processes it. Component Blade is a pretty basic blade with foreach loop. I am using the wire:init feature so that the component is not blocking the page load. It contains a custom-built pagination. When switching to the second page of data, this error occurs. It did not error out while on Livewire 1.x.

Has anyone any idea on how to tackle this problem? The error itself does not speak much to me. Any additional info required?

Thank you in advance, appreciate any help!

Markus Köhler
  • 764
  • 2
  • 8
  • 20

19 Answers19

38

In my case the solution was to make a public property protected and pass it to the blade manually, so it was excluded from Livewire's auto-handling under the hood.

Markus Köhler
  • 764
  • 2
  • 8
  • 20
  • 10
    Best answer! Livewire still having problems rehydrating same property with different values. For ecample if you have a collection. And then you change to a gruped collection. Thanks Markus. – Eric Lagarda Nov 04 '20 at 09:27
  • 3
    This answer saved my life :) Thanks. – Sinan Eldem Dec 01 '20 at 23:21
  • @EricLagarda You should add this comment as an answer. Its fixed my issue and is a totally valid answer – brenjt Apr 19 '21 at 15:24
  • Valid answer to me! – Leo May 28 '21 at 17:53
  • In my case, some public properties were being updated in a `updatedProperty` hook, which were a pain to track down. So if you don't know what exactly is generating the issue, check the updating/updated hooks. – Marian Apr 26 '22 at 15:18
  • if you need to keep track of your `$protectedProperty` on subsequent Request, then you can also pass the property to your methods like so : `wire:click="add(@js($protectedProperty))"` – Lenor Aug 08 '23 at 12:02
15

To troubleshoot this open the vendor/livewire/livewire/src/ComponentChecksumManager.php file and add var_dump($stringForHashing); on line 19, just before the return statement. Then you can see the data that is being hashed and compare it to the previous hashed data to find the discrepancies.

After I did this I was able to identify the numeric keys that javascript was re-arranging and come up with an adequate fix.

One thing to note is that some json formatters will re-order numeric keys also, so it's better to compare the json without formatting it or format it manually.

Edit: Using var_dump can interfere with the functionality on some pages, so writing the data to a file might be a better option:

file_put_contents('/path/to/log.txt', $stringForHashing . "\n\n", FILE_APPEND);
cby016
  • 1,121
  • 1
  • 10
  • 13
7

For what it worth, our issue was a very large integer, larger than what javascript can handle through Number.MAX_SAFE_INTEGER.

We filled a bug report here: https://github.com/livewire/livewire/discussions/4788 (livewire 2.10.4).

So, no solution for the bug itself when using too large integer. If you want to treat your value as a real integer you’re in no luck for now, but maybe casting to string could work for you. (and/or do your computations on the php side – with protected property – if it’s doable in your case).

That being said, the real cause of our problem was an uuid casted to int because we did not filled the protected $keyType = 'string'; of our laravel model (https://laravel.com/docs/9.x/eloquent#primary-keys)!

gorghoa
  • 71
  • 1
  • 3
  • 1
    Thank you! Ive been using snowflake implemented by `kra8/laravel-snowflake` and completely forgot about the warning regarding javascript max integer – ainesophaur Mar 31 '22 at 05:37
  • I was banging my head against the wall for the past two days and luckily found this answer. I was getting this exception whilst using an integer made of 17 digits. This should be at least documented. – bakis Apr 09 '22 at 21:05
  • 1
    Thank you for pointing this one out @user2341627 exactly the issue I had, my IDs were too large until I put 'id' => 'string' into the casts property on my models. Works fine now. – Peter Fox Apr 21 '22 at 10:10
4

i run following command then it solved

php artisan optimize

1

Addition to what others suggested above also this might happen if you have a collection which uses groupBy() might be the cause for this issue,

To fix this use protected $attribute in your component instead of public then pass $attribute to the component view.

protected $attribute;

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

...........

public function render()
{
    return view('livewire.view-here',['attribute'=>$attribute]);
}
Theodory
  • 301
  • 1
  • 3
  • 12
0

So I was getting the same error, this one:

Livewire encountered corrupt data when trying to hydrate the [component] component. Ensure that the [name, id, data] of the Livewire component wasn't tampered with between requests.

After trying the accepted answer and reading this long issue thread on Livewire's Github, I played around with passing data to the view in different ways. I'm sharing it here to help someone else with the same use case issue.

I found the following change, where an url I was previous passing I just got in the view instead, made it go away. From:

// Class
class MyComponent extends Component
{
    public Shop $shop;
    public Address $address;
    public string $action;

    // rules etc

    public function mount(Shop $shop)
    {
        if ($shop->address()->exists()) {
            $this->address = $shop->address;
            $this->form_action = route('merchant.shop.address.update');
        } else {
            $this->address = Address::make();
            $this->form_action = route('address.store');
        }
    }

// view
<div>
    <form method="post" action="{{ $action }}">
        @csrf

to:

// class
class MyComponent extends Component
{
    public Shop $shop;
    public Address $address;

    // rules etc

    public function mount(Shop $shop)
    {
        $this->address = $shop->address()->exists() ? $shop->address : Address::make();
    }

// view
<div>
    <form method="post" action="{{ $shop->address()->exists() ? route('merchant.shop.address.update') : route('address.store') }}">
forrestedw
  • 366
  • 3
  • 16
0

In my case, I had a couple of public variables and not all of them were being passed in from the parent view. After reading Markus' answer. I went and added the mount method to my livewire class and passed in the variables I was inheriting from the parent and it worked. I am using Livewire 2.3

This had the error

class MyView extends Component
{
  public $fromParent, $local;

  public function render()
  {
    return view('livewire.my-view');
  }
}

Adding mount fixed it

class MyView extends Component
{
  public $fromParent, $localVariable1, localVariable2;

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

  public function render()
  {
    return view('livewire.my-view');
  }
}
ceexon
  • 633
  • 5
  • 14
0

In my case the problem came from a database query and the resulting collection.

This query (the meaning of the variables is not important)

DB::table('progress_trackings')
        ->select('user_id')
        ->whereIn('user_id', $users->pluck('id'))
        ->where('object_id', $activity->id)
        ->where('event', $type)
        ->get()
        ->keyBy('user_id');

Produced this output:

Illuminate\Support\Collection {#2427
 all: [
   454 => {#2279
     +"user_id": 454,
   },
   528 => {#441
     +"user_id": 528,
   },
   531 => {#2368
     +"user_id": 531,
   },
 ],

The query was triggered by a button in the blade file. Clicking the button 2 or 3 times resulted in the hydration error.

In the Livewire docs it is explained that array keys sometimes can cause problems: https://laravel-livewire.com/docs/2.x/troubleshooting

So I tried to make a plain array out of the db query result. Since I only needed the keys, this worked:

DB::table('progress_trackings')
    ->select('user_id')
    ->whereIn('user_id', $users->pluck('id'))
    ->where('object_id', $activity->id)
    ->where('event', $type)
    ->get()
    ->keyBy('user_id')
    ->keys()->toArray(); // ADDED THIS

Now the result is:

[
 454,
 528,
 531,

]

Which solved the hydration error.

Dharman
  • 30,962
  • 25
  • 85
  • 135
Alex S.
  • 116
  • 6
0

I did this and it worked for me:

php artisan config:cache
php artisan config:clear
compuphys
  • 1,289
  • 12
  • 28
0

In my case it was image accessor for API i was trying to get full link image for API in model this is my mistake

public function getImageAttribute($value)
{ 
   return  $value ? url(Storage::url($value)) : ''; 
}

This cause me Livewire encountered corrupt data..

the solution in my case was

 public function getImageAttribute($value)
{
    if (Str::contains(Request()->route()->getPrefix(), 'api')) {
        return  $value ? url(Storage::url($value)) : '';
    }
    return $value;
}
Rachid Loukili
  • 623
  • 6
  • 15
0

In my case, I had the affected livewire component in another component.

//livewire component
<x-layouts.content-nosidebar title="false">
     <div class="verification section-padding">
     </div>
</x-layouts.content-nosidebar>

I removed the livewire component into its own file and I stopped getting the error.

//livewire component
<div class="verification section-padding">
</div>
Bolu
  • 1
  • 1
0

Its looking, like there are some public variables that have been either set or unset (value-filled or blank by your code) using any Livewire Hook method.

Please check those and fix them, these values are not set or unset properly during the lifecycle hook method call, I also have faced this issue and fixed it.

In my case, in the updated hook method, I have changed

This

$this->{'selectGroup.'.$value} = false;

To

$this->selectGroup[$value] = false;

Worked well for me, I hope it would make sense.

Mahesh Yadav
  • 2,416
  • 20
  • 23
0

I successfully fixed this by downgrading from php8 to php7.4

My project was running fine on Production, however for some reason I kept getting the "corrupt data when trying to hydrate" locally which used php8

I tried a ton of things, but eventually downgrading was the 1 thing that worked. Not sure what the difference is but try that.

John Cliven
  • 973
  • 1
  • 8
  • 21
0

I use custom class properties a lot, so in my case it was a hydration problem. Even when any of the upstream classes is not implementing Wireable interface, you'll get the exception.

Even for enum, which was in my case.

Component


public Notifications $notifications;

public function mount()
{
    $this->notifications = new Notifications([
        new Notification(Type::Slack);
    ]);
}

Notifications class

class Notifications implements Wireable
{
    public function toLivewire(): array
    {
         // convert to array
    }

    public function fromLivewire($value): self
    {
         // convert from array to Notifications
    }
}

Notifications class

class Notification implements Wireable
{
    public function toLivewire(): array
    {
         // convert to array
    }

    public function fromLivewire($value): self
    {
         // convert from array to Notification
    }
}

Implementing enum solved my problem

I frankly didn't know that enums can implement interfaces.

enum Type: int implements Wireable
{
    case Slack = 1;
    case Teams = 2;


    public function toLivewire(): int
    {
        return $this->value;
    }

    public static function fromLivewire($value): Type
    {
        return self::from($value);
    }
}

Hope that helps.

Darmen Amanbay
  • 4,869
  • 3
  • 29
  • 50
0

In my case, the Livewire component was referencing a model that had a custom attribute which was calculated using Carbon::now()

So that attribute had a different value every time the component tried to hyrdrate, and therefore was "corrupted".

kylepg
  • 11
  • 3
0

In my case it I was trying to store a new object in memory and save it at a later date. The object had a bunch of arrays in it which was causing the issue. Moved the arrays to separate variables and this stopped the problem, now when I save I just use those arrays.

itsgrimace
  • 96
  • 1
  • 7
0

I also struggled with this error message, which was thrown after entering a few characters in any field.

Cause: I included a livewire component by itself into an index.php page like this:

<x-layouts.frontend>

   <livewire:component-name />

</x-layouts.frontend>

Solution: Brought in surrounding HTML like this:

<x-layouts.frontend>

   // html

   <livewire:component-name />

   // html

</x-layouts.frontend>

Result: works as expected.

JimB814
  • 510
  • 8
  • 24
-1

I faced this error, when I added an array of a Value Object into the livewire component.

It was a very simple value object class like this:

class Foo {
    public string $name;
    public string $data;
}

After several hours of struggling, it became clear that solution was simply adding a $id property to the Foo class:

class Foo {
    public string $id; // a unique id
    public string $name;
    public string $data;
}

By adding $id, livewire now can keep state of a collection of objects.

armezit
  • 649
  • 1
  • 7
  • 20
-2

I solved it by putting livewire scripts @livewireScripts inside page header

<head>

<meta charset="utf-8" />

@livewireStyles

@livewireScripts

</head>