{"record":{"id":"3566f8652f8623b0","repo":"spring-projects/spring-security","slug":"failed-to-evaluate-expression-expressionstring","errorCode":null,"errorMessage":"Failed to evaluate expression '{expressionString}'","messagePattern":"Failed to evaluate expression '(.+?)'","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/springframework/security/access/expression/ExpressionUtils.java","lineNumber":38,"sourceCode":"import org.springframework.expression.EvaluationException;\nimport org.springframework.expression.Expression;\n\npublic final class ExpressionUtils {\n\n\tprivate ExpressionUtils() {\n\t}\n\n\tpublic static boolean evaluateAsBoolean(Expression expr, EvaluationContext ctx) {\n\t\ttry {\n\t\t\tBoolean result = expr.getValue(ctx, Boolean.class);\n\t\t\tif (result == null) {\n\t\t\t\tthrow new IllegalArgumentException(\n\t\t\t\t\t\t\"Expression was null but expected boolean result '\" + expr.getExpressionString() + \"'\");\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\t\tcatch (EvaluationException ex) {\n\t\t\tthrow new IllegalArgumentException(\"Failed to evaluate expression '\" + expr.getExpressionString() + \"'\",\n\t\t\t\t\tex);\n\t\t}\n\t}\n\n}\n","sourceCodeStart":20,"sourceCodeEnd":44,"githubUrl":"https://github.com/spring-projects/spring-security/blob/96852e8860138a482cb13d1479573f24ff6443c6/core/src/main/java/org/springframework/security/access/expression/ExpressionUtils.java#L20-L44","documentation":"ExpressionUtils.evaluateAsBoolean wraps Spring Expression EvaluationException into IllegalArgumentException when a SpEL security expression cannot be evaluated at all — malformed SpEL, unknown methods/properties, wrong argument types, or exceptions thrown inside the expression. The original EvaluationException is preserved as the cause.","triggerScenarios":"Any @PreAuthorize/@PostAuthorize/@PreFilter expression whose SpEL evaluation throws: referencing a non-existent bean or method, typo in a property (hasRole vs hasAuthority misuse), wrong parameter types, or el variables not present in the EvaluationContext.","commonSituations":"Typos in bean names inside @PreAuthorize; method signature changes breaking existing security expressions; SpEL syntax errors after editing annotations; missing SecurityExpressionRoot context when evaluating expressions manually.","solutions":["Read the cause (EvaluationException) attached to this IllegalArgumentException — it names the exact SpEL problem","Verify every bean/method/property referenced in the expression exists with a compatible signature","Test the expression in isolation: ExpressionParser.parseExpression(expr).getValue(ctx, Boolean.class)","Fix SpEL syntax; for null-able paths use ?. and Elvis ?: operators"],"exampleFix":"// before\n@PreAuthorize(\"@permissionService.hasPermisson(#id)\") // typo in method\n// after\n@PreAuthorize(\"@permissionService.hasPermission(#id)\")","handlingStrategy":"try-catch","validationCode":"new SpelExpressionParser().parseExpression(expressionString); // parse-check at startup","typeGuard":"null","tryCatchPattern":"try { ExpressionUtils.evaluateAsBoolean(expr, ctx); }\ncatch (IllegalArgumentException e) {\n  log.warn(\"SpEL evaluation failed: {}\", e.getCause(), e);\n  throw new AccessDeniedException(\"Invalid security expression\");\n}","preventionTips":["Startup-test all @PreAuthorize expressions by evaluating them with a mock context","Keep bean/method names in expressions in sync with refactors (IDE search)","Use constants or meta-annotations instead of hand-written duplicate SpEL","Always inspect the cause chain (EvaluationException) for the root problem"],"tags":["spel","security","expression-evaluation","authorization"],"backgroundTag":"invalid-argument-value","analyzedSha":"96852e8860138a482cb13d1479573f24ff6443c6","analyzedAt":"2026-09-10T23:25:23.477Z","contentChangedAt":"2026-09-10T23:25:23.477Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}