{"record":{"id":"5b53f445fed2bf44","repo":"alibaba/nacos","slug":"unsupported-action-action","errorCode":null,"errorMessage":"unsupported action: {action}","messagePattern":"unsupported action: (.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"warning","filePath":"plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/visibility/VisibilityGrantRoleHelper.java","lineNumber":64,"sourceCode":"    }\n    \n    static String normalizeResourceType(String resourceType) {\n        return StringUtils.isBlank(resourceType) ? resourceType\n            : resourceType.trim().toLowerCase(Locale.ROOT);\n    }\n    \n    static String normalizeStoredAction(String action) {\n        if (StringUtils.isBlank(action)) {\n            throw new IllegalArgumentException(\"action is blank\");\n        }\n        String normalized = action.trim().toLowerCase(Locale.ROOT);\n        if (\"r\".equals(normalized)) {\n            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);","sourceCodeStart":46,"sourceCodeEnd":82,"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#L46-L82","documentation":"Thrown by VisibilityGrantRoleHelper.normalizeStoredAction() when the action parameter, after trimming and lowercasing, is not one of 'r', 'w', or 'rw'. This is the raw IllegalArgumentException; within the normal service flow it is caught by DefaultVisibilityGrantService.normalizeGrantAction() and re-wrapped as NacosApiException (error 1355). The helper accepts only these three action codes and rejects anything else.","triggerScenarios":"Calling normalizeStoredAction with an action like 'read', 'write', 'delete', 'admin', 'x', or any string that isn't 'r', 'w', or 'rw' (case-insensitive). Also thrown internally by matchesRequestedAction() which calls normalizeStoredAction on the requested action.","commonSituations":"A client sends a full word ('read', 'write') instead of the abbreviation; a typo in the action field; an unexpected action value from a misconfigured client or integration.","solutions":["Use only the supported abbreviations: 'r' for read, 'w' or 'rw' for write.","Map human-readable action names to abbreviations at the API/controller layer before passing to the service.","Add a whitelist check before calling normalizeStoredAction."],"exampleFix":"// before: may throw for unrecognized actions\nString stored = VisibilityGrantRoleHelper.normalizeStoredAction(action);\n\n// after: whitelist valid actions\nprivate static final Set<String> VALID_ACTIONS = Set.of(\"r\", \"w\", \"rw\");\nString normalized = action == null ? \"\" : action.trim().toLowerCase(Locale.ROOT);\nif (!VALID_ACTIONS.contains(normalized)) {\n    throw new IllegalArgumentException(\n        \"Unsupported action: \" + action + \". Use 'r', 'w', or 'rw'.\");\n}\nString stored = VisibilityGrantRoleHelper.normalizeStoredAction(action);","handlingStrategy":"validation","validationCode":"// Whitelist valid actions before calling normalizeStoredAction\nprivate static final Set<String> VALID_ACTIONS = Set.of(\"r\", \"w\", \"rw\");\nString normalized = action == null ? \"\" : action.trim().toLowerCase(Locale.ROOT);\nif (!VALID_ACTIONS.contains(normalized)) {\n    throw new IllegalArgumentException(\n        \"Unsupported action '\" + action + \"'. Valid: r, w, rw\");\n}\nString stored = VisibilityGrantRoleHelper.normalizeStoredAction(action);","typeGuard":"public static boolean isSupportedAction(String action) {\n    if (action == null) return false;\n    String normalized = action.trim().toLowerCase(Locale.ROOT);\n    return Set.of(\"r\", \"w\", \"rw\").contains(normalized);\n}","tryCatchPattern":"try {\n    String stored = VisibilityGrantRoleHelper.normalizeStoredAction(action);\n} catch (IllegalArgumentException e) {\n    // \"unsupported action: xxx\" — map to a user-friendly error\n    log.warn(\"Unsupported action '{}': {}\", action, e.getMessage());\n    throw e;\n}","preventionTips":["Use a whitelist of valid action values ('r', 'w', 'rw') at the input layer.","Map human-readable action names to abbreviations before calling the helper.","Document the supported action codes in API documentation."],"tags":["auth","visibility","validation","action-normalization"],"backgroundTag":null,"analyzedSha":"9b989acdf181d00898f2e8839257bb2b2a3cefe3","analyzedAt":"2026-08-14T07:17:31.569Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}