{"record":{"id":"d2c1b1069fce2ac9","repo":"apereo/cas","slug":"resource-set-registration-is-missing-scopes","errorCode":null,"errorMessage":"Resource set registration is missing scopes","messagePattern":"Resource set registration is missing scopes","errorType":"validation","errorClass":"InvalidResourceSetException","httpStatus":400,"severity":"error","filePath":"support/cas-server-support-oauth-uma-core/src/main/java/org/apereo/cas/uma/ticket/resource/ResourceSet.java","lineNumber":76,"sourceCode":"    private String clientId;\n    \n    @Column(columnDefinition = \"json\")\n    @Type(JsonType.class)\n    private Set<ResourceSetPolicy> policies = new HashSet<>();\n\n    /**\n     * Validate.\n     *\n     * @param profile the profile\n     */\n    @JsonIgnore\n    public void validate(final UserProfile profile) {\n        if (StringUtils.isBlank(getClientId())) {\n            throw new InvalidResourceSetException(HttpStatus.BAD_REQUEST.value(), \"Authentication request does contain a client id\");\n        }\n\n        if (getScopes().isEmpty()) {\n            throw new InvalidResourceSetException(HttpStatus.BAD_REQUEST.value(), \"Resource set registration is missing scopes\");\n        }\n\n        if (!getOwner().equals(profile.getId())) {\n            throw new InvalidResourceSetException(HttpStatus.FORBIDDEN.value(), \"Resource-set owner does not match the authenticated profile\");\n        }\n    }\n}\n","sourceCodeStart":58,"sourceCodeEnd":84,"githubUrl":"https://github.com/apereo/cas/blob/e7288fc434b4f4505b8452e1a57e8fb3111bb863/support/cas-server-support-oauth-uma-core/src/main/java/org/apereo/cas/uma/ticket/resource/ResourceSet.java#L58-L84","documentation":"UMA resource sets must declare at least one scope. ResourceSet.validate(profile) throws InvalidResourceSetException with HTTP 400 when the scopes collection is empty, since scopes are required for later permission/policy evaluation.","triggerScenarios":"POSTing a resource-set registration (or updating one) whose body has no scopes array, an empty scopes array, or scopes that failed to deserialize, then calling ResourceSet.validate.","commonSituations":"Client omits scopes believing they're optional; JSON key mismatch (scope singular vs scopes) causing an empty collection; programmatically built ResourceSet never had addScope called.","solutions":["Add a non-empty scopes array to the resource-set registration payload","Use the exact 'scopes' JSON field name the model expects","Register/verify the scopes exist or are acceptable for the associated client","Populate scopes via addScope() when constructing ResourceSet objects in code"],"exampleFix":"// before\n{\"name\":\"photos\",\"clientId\":\"myClient\",\"scopes\":[]}\n// after\n{\"name\":\"photos\",\"clientId\":\"myClient\",\"scopes\":[\"read\",\"write\"]}","handlingStrategy":"validation","validationCode":"if (resourceSet.getScopes() == null || resourceSet.getScopes().isEmpty()) {\n  throw new IllegalArgumentException(\"At least one scope is required\");\n}","typeGuard":"boolean hasScopes(ResourceSet rs) { return rs.getScopes() != null && !rs.getScopes().isEmpty(); }","tryCatchPattern":"try { registerResourceSet(rs); } catch (InvalidResourceSetException e) { return ResponseEntity.badRequest().body(e.getMessage()); }","preventionTips":["Declare scopes alongside the resource set in the same payload","Verify scopes deserialize (correct 'scopes' key, array type)","Call addScope() when constructing ResourceSet in code"],"tags":["uma","resource-set","validation","scopes"],"backgroundTag":"missing-required-argument","analyzedSha":"e7288fc434b4f4505b8452e1a57e8fb3111bb863","analyzedAt":"2026-09-08T15:39:16.015Z","contentChangedAt":"2026-09-08T15:39:16.015Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}