{"record":{"id":"29ef77f8c07e7780","repo":"apereo/cas","slug":"cannot-save-a-resource-set-with-inconsistent-scope-29ef77","errorCode":null,"errorMessage":"Cannot save a resource set with inconsistent scopes.","messagePattern":"Cannot save a resource set with inconsistent scopes\\.","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"support/cas-server-support-oauth-uma-jpa/src/main/java/org/apereo/cas/uma/ticket/resource/repository/impl/JpaResourceSetRepository.java","lineNumber":37,"sourceCode":" * This is {@link JpaResourceSetRepository}.\n *\n * @author Misagh Moayyed\n * @since 6.0.0\n */\n@Slf4j\n@EnableTransactionManagement(proxyTargetClass = false)\n@Transactional(transactionManager = \"umaTransactionManager\")\n@ToString\npublic class JpaResourceSetRepository extends BaseResourceSetRepository {\n    private static final String ENTITY_NAME = JpaResourceSet.class.getSimpleName();\n\n    @PersistenceContext(unitName = \"umaResourceJpaContext\")\n    private EntityManager entityManager;\n\n    @Override\n    public ResourceSet save(final ResourceSet set) {\n        if (!validateResourceSetScopes(set)) {\n            throw new IllegalArgumentException(\"Cannot save a resource set with inconsistent scopes.\");\n        }\n        val jpaResource = new JpaResourceSet();\n        FunctionUtils.doUnchecked(_ -> BeanUtils.copyProperties(jpaResource, set));\n        return entityManager.merge(jpaResource);\n    }\n\n    @Override\n    public Collection<? extends ResourceSet> getAll() {\n        val query = String.format(\"SELECT r FROM %s r\", ENTITY_NAME);\n        return entityManager.createQuery(query, JpaResourceSet.class).getResultList();\n    }\n\n    @Override\n    public Optional<ResourceSet> getById(final long id) {\n        try {\n            val query = String.format(\"SELECT r FROM %s r WHERE r.id = :id\", ENTITY_NAME);\n            val resourceSet = entityManager.createQuery(query, JpaResourceSet.class)\n                .setParameter(\"id\", id)","sourceCodeStart":19,"sourceCodeEnd":55,"githubUrl":"https://github.com/apereo/cas/blob/e7288fc434b4f4505b8452e1a57e8fb3111bb863/support/cas-server-support-oauth-uma-jpa/src/main/java/org/apereo/cas/uma/ticket/resource/repository/impl/JpaResourceSetRepository.java#L19-L55","documentation":"JpaResourceSetRepository.save performs the same scope validation as the base repository before merging the ResourceSet into the 'umaResourceJpaContext' persistence unit. If the resource set's scopes are inconsistent with the registered UMA scopes, an IllegalArgumentException is thrown and nothing is persisted. This keeps JPA-backed UMA resource sets consistent with the scope registry.","triggerScenarios":"Saving a ResourceSet through the JPA repository whose scope list fails validateResourceSetScopes (unregistered/unknown scopes).","commonSituations":"JPA deployments where the service definition scopes were changed after resource sets existed; clients posting resource sets with scopes absent from cas.authn.uma configuration; typos in scope names.","solutions":["Register the resource set's scopes in the UMA/service configuration before saving.","Correct scope spellings/case to match configured scopes.","Catch IllegalArgumentException around save() and surface a 400 invalid_scope error.","Audit existing resource sets after scope configuration changes and prune unknown scopes."],"exampleFix":"// before\nset.setScopes(Set.of(\"http://example.org/unknown\"));\njpaRepo.save(set); // throws\n// after\nset.setScopes(Set.of(\"read\", \"write\")); // registered\njpaRepo.save(set);","handlingStrategy":"validation","validationCode":"Set<String> registered = umaConfiguration.getRegisteredScopes();\nif (!set.getScopes().stream().allMatch(registered::contains)) {\n    throw new IllegalArgumentException(\"unregistered scope in resource set\");\n}","typeGuard":null,"tryCatchPattern":"try { jpaRepo.save(set); } catch (IllegalArgumentException e) {\n    return ResponseEntity.badRequest().body(Map.of(\"error\", \"invalid_scope\"));\n}","preventionTips":["Synchronize JPA deployments' scope config with the service registry before saving","Run a migration script pruning unregistered scopes after config changes","Validate payloads at the REST layer before repository calls"],"tags":["uma","oauth","jpa","scope-validation"],"backgroundTag":"invalid-argument-value","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"}