{"record":{"id":"a132cb63faaa683d","repo":"prestodb/presto","slug":"role-must-be-present-for-the-selected-role-type","errorCode":null,"errorMessage":"Role must be present for the selected role type: ","messagePattern":"Role must be present for the selected role type: ","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"presto-spi/src/main/java/com/facebook/presto/spi/security/SelectedRole.java","lineNumber":65,"sourceCode":"        public int getValue()\n        {\n            return value;\n        }\n    }\n\n    private static final Pattern PATTERN = Pattern.compile(\"(ROLE|ALL|NONE)(\\\\{(.+?)\\\\})?\");\n\n    private final Type type;\n    private final Optional<String> role;\n\n    @ThriftConstructor\n    @JsonCreator\n    public SelectedRole(@JsonProperty(\"type\") Type type, @JsonProperty(\"role\") Optional<String> role)\n    {\n        this.type = requireNonNull(type, \"type is null\");\n        this.role = requireNonNull(role, \"role is null\");\n        if (type == Type.ROLE && !role.isPresent()) {\n            throw new IllegalArgumentException(\"Role must be present for the selected role type: \" + type);\n        }\n    }\n\n    @ThriftField(1)\n    @JsonProperty\n    public Type getType()\n    {\n        return type;\n    }\n\n    @ThriftField(2)\n    @JsonProperty\n    public Optional<String> getRole()\n    {\n        return role;\n    }\n\n    @Override","sourceCodeStart":47,"sourceCodeEnd":83,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-spi/src/main/java/com/facebook/presto/spi/security/SelectedRole.java#L47-L83","documentation":"SelectedRole's @JsonCreator constructor enforces that when the selected role type is Type.ROLE, a role name must be supplied; otherwise it throws IllegalArgumentException 'Role must be present for the selected role type: ROLE'. This protects the invariant that a ROLE-type selection without a role name is meaningless.","triggerScenarios":"Constructing new SelectedRole(Type.ROLE, Optional.empty()) directly, or deserializing JSON like {\"type\":\"ROLE\"} (or with \"role\": null) via Jackson, or Thrift round-trips that drop the role field.","commonSituations":"REST clients posting malformed session/authorization state to Presto's API; older clients/versions serializing SET ROLE state without the role field; hand-built thrift/json payloads for testing or internal tools.","solutions":["Supply the role name: new SelectedRole(Type.ROLE, Optional.of(\"admin\")) or include \"role\" in the JSON payload","If no role should be selected, use Type.NONE or Type.ALL with Optional.empty() instead","Fix the client serializer to always emit the role property when type is ROLE","Validate the payload client-side before posting to the Presto coordinator API"],"exampleFix":"// before\nnew SelectedRole(SelectedRole.Type.ROLE, Optional.empty());\n// after\nnew SelectedRole(SelectedRole.Type.ROLE, Optional.of(\"admin\"));\n// or, when no role applies:\nnew SelectedRole(SelectedRole.Type.NONE, Optional.empty());","handlingStrategy":"validation","validationCode":"// validate before constructing/deserializing\nif (type == SelectedRole.Type.ROLE && (role == null || !role.isPresent())) {\n    throw new IllegalArgumentException(\"ROLE type requires a role name\");\n}\nSelectedRole sr = new SelectedRole(type, role);","typeGuard":"boolean isValidSelectedRole(SelectedRole.Type type, Optional<String> role) {\n    return type != null && role != null && (type != SelectedRole.Type.ROLE || role.isPresent());\n}","tryCatchPattern":"try {\n    return objectMapper.readValue(json, SelectedRole.class);\n} catch (IllegalArgumentException e) {\n    LOG.warn(\"Invalid selected-role payload: %s\", e.getMessage());\n    return new SelectedRole(SelectedRole.Type.NONE, Optional.empty());\n}","preventionTips":["Always pair Type.ROLE with a non-empty role name","Use Type.NONE/ALL when no specific role applies","Validate incoming JSON payloads at API boundaries","Add round-trip serialization tests for SelectedRole"],"tags":["presto","validation","illegal-argument","deserialization"],"backgroundTag":"invalid-constructor-argument","analyzedSha":"55bb57d202de3b926896fa966c2c4a44c779634e","analyzedAt":"2026-09-04T12:50:26.162Z","contentChangedAt":"2026-09-04T12:50:26.162Z","schemaVersion":2},"datasetVersion":"2026-09-11T21:17:09.523Z"}