The "TypeError: Argument must be of type" error happens when a PHP function or method receives a value that doesn't match the type declared in its parameter.
A typical error looks like:
TypeError: foo(): Argument #1 ($user) must be of type User, null givenYou may also see:
TypeError: Argument #1 must be of type string, int givenor:
TypeError: Argument #2 must be of type array, null givenThis error is common in modern PHP applications and Laravel projects because PHP enforces declared parameter types more strictly.
In this guide, you'll learn why this error happens and how to fix it.
Why Does "Argument Must Be of Type" Happen?
Consider this function:
function greet(string $name)
{
return "Hello " . $name;
}The $name parameter must be a string.
This works:
greet('Ali');But this can cause a TypeError:
greet(123);The function expects a string, but the value being passed doesn't match the expected type.
The exact solution depends on what value your application is actually receiving.
Fix 1: Check the Value You're Passing
First, find the line mentioned in the TypeError.
For example:
TypeError: greet(): Argument #1 ($name) must be of type string, null givenThis tells you:
The function is
greet()The problem is argument #1
The parameter is
$namePHP expected a
stringYour code passed
null
Check the value before passing it:
$name = $user['name'] ?? '';
greet($name);Don't blindly change the function type until you understand why the wrong value is being passed.
Fix 2: Handle Null Values
One of the most common Laravel causes is a value being null.
Example:
$user = User::find($id);
sendEmail($user->email);If the user doesn't exist, $user is null and the code can fail before reaching the function.
Use:
$user = User::findOrFail($id);
sendEmail($user->email);Or check the result:
$user = User::find($id);
if ($user) {
sendEmail($user->email);
}If the function legitimately accepts null, make the parameter nullable:
function sendEmail(?string $email)
{
// ...
}The ?string means the parameter can contain either a string or null.
Fix 3: Check Laravel Request Data
A common mistake is assuming request input always has the expected type.
For example:
function findUser(int $id)
{
// ...
}
findUser(request('id'));If the request doesn't contain id, you may pass null.
Use validation:
$request->validate([
'id' => ['required', 'integer'],
]);Then:
findUser((int) $request->id);Validation is preferable to simply casting everything because it ensures the incoming data is actually valid.
Fix 4: Check Database Results
Laravel methods such as find() and first() can return null.
Example:
$user = User::where('email', $email)->first();
processUser($user);If no user exists, $user is null.
If your method requires a User object:
function processUser(User $user)
{
// ...
}use:
$user = User::where('email', $email)->firstOrFail();
processUser($user);This makes the failure explicit instead of passing null into a method that requires a User.
Fix 5: Check Argument Order
Sometimes the values are correct but passed in the wrong order.
Example:
function createUser(string $name, int $age)
{
// ...
}Incorrect:
createUser(25, 'Ali');PHP expects:
Argument #1 → string
Argument #2 → intbut receives:
Argument #1 → int
Argument #2 → stringCorrect:
createUser('Ali', 25);Check the function definition and compare every argument in the same order.
Fix 6: Use the Correct Array Type
Suppose your method expects an array:
function processUsers(array $users)
{
// ...
}This is valid:
processUsers([
'Ali',
'John',
]);But this can fail:
processUsers(null);If null is a valid possibility, either handle it before calling the method:
processUsers($users ?? []);or explicitly allow null:
function processUsers(?array $users)
{
// ...
}Use the second approach only when null actually has meaningful behavior in your application.
Fix 7: Check Object Types
A method may require a specific class:
function updateUser(User $user)
{
// ...
}Passing another object:
$post = new Post();
updateUser($post);causes a TypeError because Post is not a User.
Pass the expected object:
$user = User::findOrFail($id);
updateUser($user);Fix 8: Check Return Types
The same problem can happen with return values.
Example:
function getUserName(): string
{
return null;
}This causes a TypeError because the function promises to return a string.
If null is valid:
function getUserName(): ?string
{
return null;
}Or return a valid string:
function getUserName(): string
{
return '';
}Your declared return type should match what the function can actually return.
Fix 9: Check Laravel Model Relationships
Relationships can return null when a related record doesn't exist.
Example:
function showProfile(Profile $profile)
{
// ...
}
showProfile($user->profile);If the user has no profile, $user->profile is null.
Check first:
if ($user->profile) {
showProfile($user->profile);
}Or use a required relationship/record lookup when the relationship must exist.
Fix 10: Check PHP Type Declarations
Your function may have a strict type declaration:
function calculateTotal(float $price, int $quantity)
{
return $price * $quantity;
}Make sure you're passing appropriate values:
calculateTotal(99.99, 2);If the application receives data from forms, APIs, or databases, validate and normalize it before passing it to strongly typed methods.
How to Find the Exact Cause
The error message usually contains everything you need.
For example:
TypeError: UserService::find(): Argument #1 ($id)
must be of type int, string givenLook at:
1. The function or method
UserService::find()2. The argument number
Argument #13. The expected type
int4. The actual type
stringThis tells you exactly what needs investigation.
Debug the Value Before Passing It
If you're unsure what your code is receiving, inspect the value:
dd($value);or:
dump($value);You can also check its type:
dd(gettype($value), $value);For objects:
dd(get_class($value));Once you know the actual value and type, the correct fix becomes much easier to identify.
Don't Just Remove the Type Declaration
You may find advice suggesting you change:
function processUser(User $user)to:
function processUser($user)This removes the immediate TypeError, but it may simply hide the underlying problem.
If the method genuinely requires a User, keep the type declaration and fix the value being passed to it.
Strong typing helps catch bugs early.
Final Checklist
When you see:
TypeError: Argument must be of typecheck:
✓ Read the complete error message
✓ Identify the argument number
✓ Check the expected type
✓ Check the actual value being passed
✓ Check for unexpected
nullvalues✓ Check Laravel
find()andfirst()results✓ Validate request input
✓ Check argument order
✓ Check model relationships
✓ Verify return type declarations
✓ Keep type declarations unless the parameter genuinely supports another type
The important part is not simply changing the expected type. Find out why your code is receiving the wrong value in the first place.
If your PHP or Laravel application is showing a TypeError and you're unsure what is causing it, send me the complete error message and the relevant function or method. I can help identify the exact mismatch and the correct fix.