SonarSource/sonarqube · error · IllegalArgumentException
Provided user with login '%s' does not have 'Browse' permiss
Error message
Provided user with login '%s' does not have 'Browse' permission to project
What it means
Thrown by the assign action of the Security Hotspots web service when the user chosen as assignee cannot see the project the hotspot belongs to. For private projects, SonarQube requires that any assignable user holds the 'Browse' (USER) permission on the project. The server rejects the assignment rather than silently granting visibility.
Source
Thrown at server/sonar-webserver-webapi/src/main/java/org/sonar/server/hotspot/ws/AssignAction.java:158
}
}
private static void checkHotspotStatusAndResolution(IssueDto hotspotDto) {
if (!STATUS_TO_REVIEW.equals(hotspotDto.getStatus()) && !RESOLUTION_ACKNOWLEDGED.equals(hotspotDto.getResolution())) {
throw new IllegalArgumentException("Cannot change the assignee of this hotspot given its current status and resolution");
}
}
private UserDto getAssignee(DbSession dbSession, String assignee) {
return checkFound(dbClient.userDao().selectActiveUserByLogin(dbSession, assignee), "Unknown user: %s", assignee);
}
private void checkAssigneeProjectPermission(DbSession dbSession, UserDto assignee, String issueBranchUuid) {
ProjectDto project = checkFoundWithOptional(dbClient.projectDao().selectByBranchUuid(dbSession, issueBranchUuid),
"Could not find branch for issue");
if (project.isPrivate() && !hasProjectPermission(dbSession, assignee.getUuid(), project.getUuid())) {
throw new IllegalArgumentException(String.format("Provided user with login '%s' does not have 'Browse' permission to project", assignee.getLogin()));
}
}
private boolean hasProjectPermission(DbSession dbSession, String userUuid, String projectUuid) {
return dbClient.authorizationDao().selectEntityPermissions(dbSession, projectUuid, userUuid).contains(ProjectPermission.USER.getKey());
}
private static HotspotChangedEvent buildEventData(DefaultIssue defaultIssue, @Nullable UserDto assignee, String filePath) {
return new HotspotChangedEvent.Builder()
.setKey(defaultIssue.key())
.setProjectKey(defaultIssue.projectKey())
.setStatus(defaultIssue.status())
.setResolution(defaultIssue.resolution())
.setUpdateDate(defaultIssue.updateDate())
.setAssignee(assignee == null ? null : assignee.getLogin())
.setFilePath(filePath)
.build();
}View on GitHub (pinned to 184c821202)
Solutions
- Grant the assignee the 'User' (Browse) permission on the project in Project Settings > Permissions
- Check the user has access via GET api/permissions/users with projectKey before assigning
- Assign to a different user who already has Browse permission
- If the project should be public, change visibility in Project Settings so the check is skipped
Example fix
// before curl -X POST '.../api/hotspots/assign?hotspot=AX1&assign=ci-bot' // after # grant permission first, then assign curl -X POST '.../api/permissions/add_user?projectKey=my_project&login=ci-bot&permission=user' curl -X POST '.../api/hotspots/assign?hotspot=AX1&assign=ci-bot'
Defensive patterns
Strategy: validation
Validate before calling
const perms = await get('/api/permissions/users', {projectKey, login: assigneeLogin, permission: 'user'});
if (!perms.permissions.some(p => p.login === assigneeLogin)) throw new Error('assignee lacks Browse permission'); Try / catch
try { await post('/api/hotspots/assign', {hotspot, assign: login}); } catch (e) { if (e.status === 400 && e.message.includes("does not have 'Browse'")) { /* grant permission or pick another user */ } else throw e; } Prevention
- Check assignee's project permissions before any automated assignment
- Maintain a list of assignable users synced with project permissions
- Avoid assigning to service/bot accounts lacking Browse access
When it happens
Trigger: Calling POST api/hotspots/assign with an 'assign' login whose user is not in the project's USER permission list while the project is private. The check only runs for private projects, so public projects never hit it.
Common situations: Assigning a hotspot to an admin or bot account that was never granted project access; assigning to a user of another organization; project visibility switched to private after users were assigned previously; automated scripts using a service account without Browse permission.
Understand the failure class
Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.
Related errors
- Project '%s' not found
- Insufficient privileges
- Insufficient privileges
- Insufficient privileges
- Insufficient privileges
AI-assisted analysis of SonarSource/sonarqube@184c821202 (2026-09-09).
Data as JSON: /api/errors/f4bf00ee137cd48a.
Report an issue: GitHub.