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

troccoli's avatar

Odd issue with casting on SQLite database

I really hope someone could shed some light becuase I haven't got a clue what could be wrong.

I have a project that generates calendar events and send them to a Google calendar. The events are first generated locally and then sent to Google. Both of these operations are done by jobs, and they are queued.

My app was running PHP 8.3.15, Laravel10.43.0, SQLite 3.40.1 on a Raspberry Pi 5. It was working perfectly.

I then decided to upgrade the app to Laravel 11, but it's not working. It rans on the same Raspberry Pi, so same version of PHP and SQLite.

The new app works fine if I use the sync queue. But if I use the database queue it looks like the Eloquent model is not quite right. I'll try and explain.

The job to generate the events received an EventsJob model which contains the start and end date. It then canculates how many events to generate (one per day) and this is where I get the error

Call to a member function diffInDays() on string

It looks like the start date (nor the end date for that matter) was cast to a CarbonImmutable.

I'm really buffled because as I said the old app works fine with both sync and database queue, and the new app works fine with the sync queue.

Now for some code.

class EventsJob extends Model
{
    \\ ...

    protected function casts(): array
    {
        return [
            'start' => 'immutable_date',
            'end' => 'immutable_date',
            'status' => JobStatus::class,
        ];
    }

    \\ ...
}
class GenerateEvents implements ShouldQueue
{
    \\ ...

    public function __construct(
        #[WithoutRelations]
        public EventsJob $eventsJob,
    ) {}

    public function handle(RotaPdfParser $service): void
    {
        \\ This is where I get the "Call to a member function diffInDays() on string" error
        $events = (int) $this->eventsJob->start->diffInDays($this->eventsJob->end) ;
        \\ ...
    }

    \\ ...
}

It's possible I may have done something wrong with upgrading. It's a small app and instead of following the upgrade notes I created a brand new app and ported the code.

Any ideas of what to check will be very much appreciated.

0 likes
2 replies
LaryAI's avatar
Level 58

The issue you're encountering seems to be related to the casting of your start and end attributes in the EventsJob model. In Laravel 11, there might be changes in how casting is handled, especially when dealing with queued jobs and serialization.

Here are a few steps you can take to troubleshoot and potentially resolve the issue:

  1. Check Casting Method Signature: Ensure that the casts method in your model is correctly defined. In Laravel, the casts property is typically an array, not a method. You should define it as a property like this:

    class EventsJob extends Model
    {
        // ...
    
        protected $casts = [
            'start' => 'immutable_date',
            'end' => 'immutable_date',
            'status' => JobStatus::class,
        ];
    
        // ...
    }
    
  2. Serialization of Models in Jobs: When a job is serialized, the model's attributes are stored as plain data. Upon deserialization, Laravel should automatically cast these attributes back to their defined types. However, if there's an issue with the casting, it might be due to how the model is being serialized or deserialized.

  3. Check for Serialization Issues: Ensure that your EventsJob model is correctly serialized and deserialized. You can add some logging in the handle method to check the types of start and end after the job is deserialized:

    public function handle(RotaPdfParser $service): void
    {
        // Log the types of start and end
        \Log::info('Start type: ' . gettype($this->eventsJob->start));
        \Log::info('End type: ' . gettype($this->eventsJob->end));
    
        $events = (int) $this->eventsJob->start->diffInDays($this->eventsJob->end);
        // ...
    }
    
  4. Check for Custom Serialization Logic: If you have any custom serialization logic in your model or job, ensure that it correctly handles the casting of attributes.

  5. Review Laravel Upgrade Notes: Since you mentioned creating a new app and porting the code, double-check the Laravel 11 upgrade guide to ensure there are no additional changes that might affect model casting or job serialization.

By following these steps, you should be able to identify and resolve the issue with the casting of your start and end attributes in the EventsJob model. If the problem persists, consider creating a minimal reproducible example and testing it in isolation to further diagnose the issue.

troccoli's avatar
troccoli
OP
Best Answer
Level 6

As usual, a nice walk away from the computer solved it. I feel like an idiot.

All I had to do was to restart the queue worker, which I had probably started which I bad version of the app (while I was doing some deployment testing).

php artisan queue:restart

Please or to participate in this conversation.