apereo/cas · warning

Groovy-scripted attribute returned no value for

Error message

Groovy-scripted attribute returned no value for [{}]

What it means

The WS-Federation release policy executes a Groovy script (inline or external file) to compute a claim value; the script ran but returned null, so no value could be mapped and the claim is skipped with this warning.

Solutions

  1. Review the Groovy script and make it return a value (or a sane default) for all principals
  2. Log inside the script to confirm the binding attributes it reads actually exist
  3. Fix the attribute name the script reads to match the principal's attribute keys
  4. If the claim is optional, treat the warning as benign; otherwise correct user data

Example fix

// before
def email = attributes['mail']; return null
// after
def email = attributes?.getFirst('mail'); return email ?: "unknown@example.invalid"
Defensive patterns

Strategy: validation

Validate before calling

// pre-check the script produces a non-null result for a sample user
Object r = new GroovyShell().evaluate(scriptSource);
if (r == null) LOGGER.warn("Script returns null");

Prevention

When it happens

Trigger: fetchAttributeValueFromScript runs the Groovy script for the claim; script.execute(...) returns null for the given binding of principal/attributes/service.

Common situations: Script logic has a code path returning null for the user (missing attribute access); wrong attribute key accessed in the binding; external .groovy file deployed but written for a different attribute; syntax silently swallowing an error and returning null.

Understand the failure class

Background: EmptyResultError / "no results found": when an API or scraper succeeds but returns zero rows — this error's family across 9 libraries.

Related errors


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

Appendix: source

Thrown at support/cas-server-support-ws-idp-api/src/main/java/org/apereo/cas/ws/idp/services/WSFederationClaimsReleasePolicy.java:153

                },
                () -> {
                    throw new RuntimeException("No groovy script cache manager is available to execute attribute mappings");
                });
    }

    private static void fetchAttributeValueFromScript(final ExecutableCompiledScript script,
                                                      final String attributeName,
                                                      final Map<String, List<Object>> resolvedAttributes,
                                                      final Map<String, List<Object>> attributesToRelease) {
        FunctionUtils.doUnchecked(_ -> {
            val args = CollectionUtils.wrap("attributes", resolvedAttributes, "logger", LOGGER);
            script.setBinding(args);
            val result = script.execute(args.values().toArray(), Object.class);
            if (result != null) {
                LOGGER.debug("Mapped attribute [{}] to [{}] from script", attributeName, result);
                attributesToRelease.put(attributeName, CollectionUtils.wrapList(result));
            } else {
                LOGGER.warn("Groovy-scripted attribute returned no value for [{}]", attributeName);
            }
        });
    }

    @Override
    public List<String> determineRequestedAttributeDefinitions(final RegisteredServiceAttributeReleasePolicyContext context) {
        return new ArrayList<>(getAllowedAttributes().keySet());
    }
}

View on GitHub (pinned to e7288fc434)