When assigning a role to a user with:
$user->assignRole('name');
The app is trying to find the role using the first guard from the 'guards' list in auth.php but not from the default guard. This is not the same behavior as when creating a role, which creates it using the default guard.
my setup:
'defaults' => [
'guard' => 'api',
'passwords' => 'users',
],
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'token',
'provider' => 'users',
],
],
# Uses api for the guard_name
Role::create(['name' => 'admin']);
# Uses web for the guard_name
$user->assignRole('name');
What's the guard_name property on your User model (whatever your $user object is created from)?
It has none set.
use App\User;
$user = new User();
$user->guard_name;
# null
$user->assignRole('name'); is taking the one that comes first in the guards array. I changed the order in the array to api first, and it then uses the api guard.
This solved my issue.

@drbyte May I ask if this was fixed? Or, if not, why is the issue closed?
Thanks
Sigh. Thanks for catching that. I misread the last post as being a resolution.
Dear contributor,
because this issue seems to be inactive for quite some time now, I've automatically closed it. If you feel this issue deserves some attention from my human colleagues feel free to reopen it.
I was just reviewing this again.
I think it is resolved.
Role::create and assignRole() both use this package's ->getDefaultGuardName(), which first looks for $guard_name as a property on the model, and if not found will fallback to Laravel's default guard.
In my case it's not falling back to Laravel's default. Having to enforce:
/**
* The guard for `laravel-permissions` to use.
*
* Patching `Spatie\Permission\Guard` because it's not picking up Laravel's default.
*
* @return string
*/
public function guardName(): string
{
return 'api';
}
on my User model.
Most helpful comment
Sigh. Thanks for catching that. I misread the last post as being a resolution.