Laravel Passport Trying to get property 'secret' of non-object
Stefan Bogdanescu
Founder & Senior Architect · 2026-06-29
# Laravel Passport Error: Why You See "Trying to get property 'secret' of non-object"
As a senior developer working with Laravel and API security, I’ve seen countless developers run into confusing exceptions when implementing systems like Laravel Passport or Sanctum. The error you are encountering—`Trying to get property 'secret' of non-object`—is notoriously frustrating because it often points to a deep configuration issue rather than a simple typo in the controller code.
This post will dive deep into why this specific error occurs during token creation with Laravel Passport and provide a comprehensive, step-by-step guide to resolving it.
## Understanding the Error Context
You are attempting to use the method `$user->createToken('authToken')->accessToken;` within your `AuthController`. This process relies entirely on the underlying Eloquent model (`$user`) correctly implementing the necessary interfaces provided by the Passport package.
The error message, "Trying to get property 'secret' of non-object," tells us exactly what went wrong: Laravel Passport’s internal factory is expecting an object that possesses a `secret` property (which is used internally for signing tokens), but instead, it received something that was *not* an Eloquent model instance—likely `null` or some other unexpected type.
This usually means the `$user` variable you are calling methods on is not a valid Eloquent model object when Passport tries to process the request.
## Root Cause Analysis: Model Setup is Key
In 99% of cases where this error occurs during token generation, the problem resides in the setup of your User model or the installation of Passport itself, not the controller logic itself.
Here are the most common culprits:
1. **Missing Trait:** The most frequent cause is forgetting to include the necessary trait that grants Eloquent models the ability to handle API tokens.
2. **Model Instantiation Failure:** Although you use `User::create()`, if there were any underlying database constraint failures or custom model events, it might return an unexpected result (though less likely with `create()`).
3. **Passport Installation Flaw:** Issues during the initial Passport setup can sometimes lead to broken relationships or service bindings.
## Step-by-Step Solution and Debugging
To fix this, we need to systematically debug your setup, following best practices outlined by the Laravel team.
### 1. Verify the `HasApiTokens` Trait
Ensure that your `App\Models\User` model correctly implements the necessary interface for Passport functionality. You must use the `Laravel\Passport\HasApiTokens` trait.
**In `app/Models/User.php`:**
```php
validate([
'name' => 'required|max:55',
'email' => 'email|required|unique:users',
'password' => 'required|confirmed',
'who' => 'required'
]);
$user = User::create($validatedData);
// CRITICAL CHECK: Ensure the user was actually created before proceeding
if (!$user) {
return response()->json(['message' => 'User creation failed'], 422);
}
try {
// Get access token
$accessToken = $user->createToken('authToken')->accessToken;
return response([
'user' => $user,
'access_token' => $accessToken
]);
} catch (\Exception $e) {
// Catch any unexpected Passport errors here for better debugging
return response()->json(['message' => 'Token generation failed: ' . $e->getMessage()], 500);
}
}
```
## Conclusion
The error "Trying to get property 'secret' of non-object" in a Laravel Passport context is almost always a symptom pointing back to an improperly configured Eloquent model, specifically the missing `HasApiTokens` trait on your User model. By rigorously checking your model setup and ensuring proper integration with the framework, you will resolve this issue and successfully implement secure token-based authentication. Keep up the great work building robust APIs!