apereo/cas · warning

Groovy script [ ] does not exist or cannot be loaded

Error message

Groovy script [{}] does not exist or cannot be loaded

What it means

GroovySamlRegisteredServiceAttributeReleasePolicy.getAttributesForSamlRegisteredService() executes the configured Groovy script from the script cache to compute released attributes. If the script resource cannot be located or loaded (Optional empty from the cache lookup), it logs this warning and returns an empty attribute map; if no script cache manager exists at all it throws a RuntimeException. Either way no attributes are released from the script.

Solutions

  1. Verify the script path/URL in the service definition resolves from the CAS server (test with file/classpath resource access) and is readable by the CAS user
  2. Check the script compiles by executing it standalone or watching startup logs for Groovy compilation errors
  3. Ensure the Groovy script cache manager is available (correct CAS module/wiring) so the policy does not throw
  4. Return a valid Map<String,List<Object>> from the script; an empty map is the safe no-attributes contract

Example fix

// before: wrong path in service policy
"groovyScript" : "file:/etc/cas/scripts/attr-release.groovy.bak"
// after
"groovyScript" : "file:/etc/cas/scripts/attr-release.groovy"
Defensive patterns

Strategy: validation

Validate before calling

// check the script resource before configuring the policy
val f = new File('/etc/cas/scripts/attr-release.groovy');
if (!f.isFile() || !f.canRead()) throw new FileNotFoundException(f.getPath());

Type guard

function scriptLoaded(cache, path) { return cache != null && cache.resolveScriptResource(path).isPresent(); }

Try / catch

try { attrs = policy.getAttributesInternal(...); }
catch (RuntimeException e) { log.error('Groovy policy failed: no script cache', e); attrs = Map.of(); }

Prevention

When it happens

Trigger: A service's attribute release policy references a Groovy script path that does not exist, is misfiled (relative vs classpath/file: URL), or fails to compile/load; or the policy runs without a Groovy script cache manager bean configured.

Common situations: Typo in file:groovy path in the service definition JSON; script not deployed to the CAS server filesystem or classpath; file permissions denying read; moving from inline Groovy to external script after an upgrade; cache manager not initialized in a custom wiring.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


AI-assisted analysis of apereo/cas@e7288fc434 (2026-09-08). Data as JSON: /api/errors/6bf71c4eae26d320. Report an issue: GitHub.

Appendix: source

Thrown at support/cas-server-support-saml-idp-core/src/main/java/org/apereo/cas/support/saml/services/GroovySamlRegisteredServiceAttributeReleasePolicy.java:57

    protected Map<String, List<Object>> getAttributesForSamlRegisteredService(
        final Map<String, List<Object>> attributes,
        final SamlRegisteredServiceCachingMetadataResolver resolver,
        final SamlRegisteredServiceMetadataAdaptor facade,
        final EntityDescriptor entityDescriptor,
        final RegisteredServiceAttributeReleasePolicyContext context) {

        return ApplicationContextProvider.getScriptResourceCacheManager()
            .map(cacheMgr -> {
                val groovyResource = SpringExpressionLanguageValueResolver.getInstance().resolve(this.groovyScript);
                val script = cacheMgr.resolveScriptableResource(groovyResource, groovyResource);
                return Optional.ofNullable(script)
                    .map(Unchecked.function(sc -> {
                        val args = new Object[]{attributes, context.getRegisteredService(), resolver,
                            facade, entityDescriptor, context.getApplicationContext(), LOGGER};
                        return (Map<String, List<Object>>) script.execute(args, Map.class, true);
                    }))
                    .orElseGet(() -> {
                        LOGGER.warn("Groovy script [{}] does not exist or cannot be loaded", groovyScript);
                        return new HashMap<>();
                    });
            })
            .orElseThrow(() -> new RuntimeException("No groovy script cache manager is available to execute attribute mappings"));
    }
}

View on GitHub (pinned to e7288fc434)