{"record":{"id":"a85ecbaa03a0c705","repo":"alibaba/nacos","slug":"username-is-blank-a85ecb","errorCode":null,"errorMessage":"username is blank","messagePattern":"username is blank","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/visibility/VisibilityGrantRoleHelper.java","lineNumber":77,"sourceCode":"            return \"r\";\n        }\n        if (\"w\".equals(normalized) || \"rw\".equals(normalized)) {\n            return \"rw\";\n        }\n        throw new IllegalArgumentException(\"unsupported action: \" + action);\n    }\n    \n    static boolean matchesRequestedAction(String storedAction, String requestedAction) {\n        String normalizedRequested = normalizeStoredAction(requestedAction);\n        if (\"rw\".equals(normalizedRequested)) {\n            return \"rw\".equals(storedAction);\n        }\n        return \"r\".equals(storedAction) || \"rw\".equals(storedAction);\n    }\n    \n    static String buildUserRoleName(String username) {\n        if (StringUtils.isBlank(username)) {\n            throw new IllegalArgumentException(\"username is blank\");\n        }\n        // Use a deterministic short SHA-256 prefix so internal role names stay within\n        // the existing roles.role varchar(50) limit and do not expose user names.\n        return buildUserRoleNamePrefix() + sha256LowerHex(username).substring(0,\n            USER_ROLE_HASH_HEX_LENGTH);\n    }\n    \n    static String buildUserRoleNamePrefix() {\n        return AuthConstants.VISIBILITY_GRANT_ROLE_PREFIX + USER_ROLE_MARKER;\n    }\n    \n    static boolean isUserGrantRole(String roleName) {\n        return StringUtils.isNotBlank(roleName) && roleName.startsWith(buildUserRoleNamePrefix());\n    }\n    \n    static String buildResourceIdentifier(String namespaceId, String resourceType,\n        String resourceName) {\n        return RESOURCE_IDENTIFIER_PREFIX + normalizeNamespaceId(namespaceId) + \"/\"","sourceCodeStart":59,"sourceCodeEnd":95,"githubUrl":"https://github.com/alibaba/nacos/blob/9b989acdf181d00898f2e8839257bb2b2a3cefe3/plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/visibility/VisibilityGrantRoleHelper.java#L59-L95","documentation":"Thrown by VisibilityGrantRoleHelper.buildUserRoleName when the supplied username is null, empty, or whitespace-only. The method builds a deterministic internal role name (prefix + SHA-256 hex of the username) used to persist visibility grants, so a blank username would produce an ambiguous or insecure role key. It throws IllegalArgumentException to refuse degenerate input early.","triggerScenarios":"Calling buildUserRoleName(username) where username is null, an empty string \"\", or contains only whitespace. This happens when a visibility-grant granting API or persistence path receives a user identifier that was never validated upstream.","commonSituations":"A REST/controller layer passes a request DTO's username field straight into the visibility grant service without blank-checking it; or a background reconciliation/migration job iterates over a user list that contains null entries.","solutions":["Validate the username with StringUtils.isBlank(username) before calling buildUserRoleName and reject the request with a clear 400-level error.","Trace the call chain upward to find which API endpoint or job feeds an empty username and fix the source of the bad data.","If calling from an internal loop, filter out null/blank usernames before processing the batch."],"exampleFix":"// before\nString roleName = VisibilityGrantRoleHelper.buildUserRoleName(username);\n\n// after\nif (StringUtils.isBlank(username)) {\n    throw new IllegalArgumentException(\"username is blank\");\n}\nString roleName = VisibilityGrantRoleHelper.buildUserRoleName(username);","handlingStrategy":"validation","validationCode":"if (StringUtils.isBlank(username)) {\n    throw new IllegalArgumentException(\"username is blank\");\n}\n// safe to call\nString roleName = VisibilityGrantRoleHelper.buildUserRoleName(username);","typeGuard":"static boolean isValidUsernameForRole(String username) {\n    return username != null && !username.trim().isEmpty();\n}","tryCatchPattern":"try {\n    roleName = VisibilityGrantRoleHelper.buildUserRoleName(username);\n} catch (IllegalArgumentException e) {\n    // return 400 with validation message, do not retry\n}","preventionTips":["Always blank-check user-supplied identifiers at the controller/API boundary before passing to internal helpers.","Use StringUtils.isBlank (handles null, empty, and whitespace) rather than manual null checks.","Add unit tests for the null/empty/whitespace username cases."],"tags":["auth","validation","visibility","illegal-argument","java"],"backgroundTag":null,"analyzedSha":"9b989acdf181d00898f2e8839257bb2b2a3cefe3","analyzedAt":"2026-08-14T07:17:31.569Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}