prestodb/presto · error · IllegalArgumentException

Role must be present for the selected role type:

Error message

Role must be present for the selected role type: 

What it means

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.

Source

Thrown at presto-spi/src/main/java/com/facebook/presto/spi/security/SelectedRole.java:65

        public int getValue()
        {
            return value;
        }
    }

    private static final Pattern PATTERN = Pattern.compile("(ROLE|ALL|NONE)(\\{(.+?)\\})?");

    private final Type type;
    private final Optional<String> role;

    @ThriftConstructor
    @JsonCreator
    public SelectedRole(@JsonProperty("type") Type type, @JsonProperty("role") Optional<String> role)
    {
        this.type = requireNonNull(type, "type is null");
        this.role = requireNonNull(role, "role is null");
        if (type == Type.ROLE && !role.isPresent()) {
            throw new IllegalArgumentException("Role must be present for the selected role type: " + type);
        }
    }

    @ThriftField(1)
    @JsonProperty
    public Type getType()
    {
        return type;
    }

    @ThriftField(2)
    @JsonProperty
    public Optional<String> getRole()
    {
        return role;
    }

    @Override

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Supply the role name: new SelectedRole(Type.ROLE, Optional.of("admin")) or include "role" in the JSON payload
  2. If no role should be selected, use Type.NONE or Type.ALL with Optional.empty() instead
  3. Fix the client serializer to always emit the role property when type is ROLE
  4. Validate the payload client-side before posting to the Presto coordinator API

Example fix

// before
new SelectedRole(SelectedRole.Type.ROLE, Optional.empty());
// after
new SelectedRole(SelectedRole.Type.ROLE, Optional.of("admin"));
// or, when no role applies:
new SelectedRole(SelectedRole.Type.NONE, Optional.empty());
Defensive patterns

Strategy: validation

Validate before calling

// validate before constructing/deserializing
if (type == SelectedRole.Type.ROLE && (role == null || !role.isPresent())) {
    throw new IllegalArgumentException("ROLE type requires a role name");
}
SelectedRole sr = new SelectedRole(type, role);

Type guard

boolean isValidSelectedRole(SelectedRole.Type type, Optional<String> role) {
    return type != null && role != null && (type != SelectedRole.Type.ROLE || role.isPresent());
}

Try / catch

try {
    return objectMapper.readValue(json, SelectedRole.class);
} catch (IllegalArgumentException e) {
    LOG.warn("Invalid selected-role payload: %s", e.getMessage());
    return new SelectedRole(SelectedRole.Type.NONE, Optional.empty());
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04). Data as JSON: /api/errors/a132cb63faaa683d. Report an issue: GitHub.