Fixing Spatie Permission Exceptions PermissionDoesNotExist Error in Laravel 12
The spatie/laravel-permission
package is one of the most powerful and widely used role-permission management solutions for Laravel. However, many developers encounter the dreaded error:
Spatie\Permission\Exceptions\PermissionDoesNotExist
There is no permission named `1` for guard `web`
Or:
There is no permission named `edit_project` for guard `api`
Why This Error Happens
These errors usually appear when:
- You try to assign permission by ID instead of name (or vice versa)
- You’re using mismatched guards (e.g., assigning an
api
permission to aweb
role)
Understanding How syncPermissions()
Works
The syncPermissions()
method expects either permission names or permission model instances. If you pass an array like [1, 2]
, it interprets these as permission names, not IDs. So it looks for permissions literally named 1
and 2
.
Incorrect Example
$role->syncPermissions([1, 2, 3]); // Will cause an error
Correct Way: Cast IDs to Integers
$data = [];
foreach ($permissions as $key => $item) {
$data[$key] = (int) $item;
}
if (!empty($data)) {
$role->syncPermissions($data);
}
Step-by-Step Example
1. Create Permissions and Roles
Permission::create(['name' => 'edit_project']);
Role::create(['name' => 'manager']);
2. UI Form Submission
3. Backend Controller
$permissions = $request->input('permissions'); // ['1', '2']
$data = [];
foreach ($permissions as $key => $item) {
$data[$key] = (int) $item;
}
if (!empty($data)) {
$role->syncPermissions($data);
}
Guard Mismatches
Make sure your guards match. For example, if you're using the api
guard, define roles and permissions accordingly:
Permission::create(['name' => 'edit_project', 'guard_name' => 'api']);
Role::create(['name' => 'editor', 'guard_name' => 'api']);
Alternative: Sync Directly to Pivot Table
If you know what you’re doing and want to bypass Spatie’s logic:
$role->permissions()->sync([1, 2, 3]);
Helper Function
function castPermissionIds(array $permissions): array {
return array_map('intval', $permissions);
}
Best Practices
- Use seeder files to define and assign permissions
- Ensure guards match across permissions and roles
- Use helper functions to sanitize input
- Log failed permission lookups during debugging
Conclusion
The PermissionDoesNotExist
error in Laravel can be tricky but is very solvable. By understanding how the syncPermissions()
function works and ensuring data types are correct, you can eliminate this issue and build secure, flexible role-permission systems in your application.