Laravel 8 ErrorException: Trying to access array offset on value of type null
Stefan Bogdanescu
Founder & Senior Architect · 2026-06-29
Decoding the Error: Fixing ErrorException: Trying to access array offset on value of type null in Laravel
As a senior developer working with the Laravel ecosystem, debugging runtime errors is a daily reality. One of the most frustrating yet common errors developers encounter is ErrorException: Trying to access array offset on value of type null. This error usually signals a mismatch between what your code expects (an array) and what it actually receives (null or a non-array type, like a string).
Today, we will dissect the specific issue you are facing with accessing image data in your Laravel application, examine the data flow from your controller to the view, and provide a robust solution. We will ensure your Eloquent models and Blade templates work harmoniously, following best practices that align with how powerful tools like those offered by Laravel are designed to function.
The Diagnosis: Where is the Data Breaking Down?
You are encountering this error on the line: @foreach($article->images['images'] as $key => $image). This statement assumes that $article->images is an array, and it contains a nested array keyed by 'images'.
Based on your provided debug output (dd($article)), we see the root of the problem immediately:
// Output of dd($article):
// "images" => "F:\xampp\tmp\php1825.tmp"
The issue is clear: the $article->images attribute, which you expect to be an array (because you set $casts = ['images' => 'array']), is actually being populated with a single file path string instead of an array of image paths. When PHP tries to execute $article->images['images'], it attempts to access an offset on a string, leading directly to the Trying to access array offset on value of type null error (or similar type-related errors depending on how PHP handles the failed operation).
The problem isn't in the Blade syntax itself; it is entirely in the data structure being passed from your model to the view.
Tracing the Data Flow and Identifying the Bug
Let’s trace where this incorrect data originates:
ArticleModel Casting: You correctly set$casts = ['images' => 'array'];. This tells Eloquent that when retrievingimages, it should attempt to cast the raw database value into an array.storeMethod &uploadImages: The logic in your controller seems to be storing only one final file path:// Inside AdminController::uploadImages $url['images'] = $this->resize($file->getRealPath(), $sizes, $imagePath, $filename); $url['thumb'] = $url['images'][$sizes[0]]; // Only storing one thumb path here? return $url;The
resizeFunction: The function returns an array$imagescontaining paths likeoriginal,300,600, etc., but the logic seems to assign only a single resulting path back into the main structure, leading to$article->imagesbeing set to that single string value.
The core flaw is that your image handling logic is serializing multiple files into a single string instead of collecting them into an array property before saving it to the database.
The Solution: Restructuring Data for Correct Access
To fix this, we must ensure that when you save the data to the database, you are storing the entire set of image paths as a JSON-encoded string (if necessary) or, better yet, as a true array if your database supports JSON types. Since you have casting configured, the cleanest solution is ensuring the model receives an actual PHP array upon retrieval.
Step 1: Correcting the Saving Logic (Controller/AdminController)
You need to restructure what you are saving into the images column. Instead of storing a single path string, store the resulting image paths as an array.
Assuming your database column for images is capable of storing JSON (which modern MySQL/PostgreSQL supports), modify your saving logic to ensure $imageUrl['images'] holds the actual array of file paths:
// In AdminController::uploadImages or the store method context
protected function uploadImages($file)
{
$year = Carbon::now()->year;
$imagePath = "/upload/images/{$year}/";
$filename = $file->getClientOriginalName();
$file = $file->move(public_path($imagePath), $filename);
$sizes = ["300", "600", "900"];
$imagePaths = []; // Initialize an array to hold paths
$imagesData = $this->resize($file->getRealPath(), $sizes, $imagePath, $filename);
// Collect all generated paths into a single array for saving