projectlombok/lombok · error · AnnotationValueDecodeFail
You must use constant literals in lombok annotations; they…
Error message
You must use constant literals in lombok annotations; they cannot be references to (static) fields.
What it means
Java's language rules require annotation values to be compile-time constants; lombok's guessToType() rejects FieldSelect guesses outright because a field reference is (potentially) not a constant literal. This AnnotationValueDecodeFail tells the user to inline the constant value instead of referencing a (static) field in a lombok annotation.
Solutions
- Inline the literal value directly into the annotation (copy the constant's value).
- Keep the constant but only use it in non-annotation code; annotations must use literals.
- If the value is genuinely constant and resolvable (e.g. an enum constant or class literal), write it in the form lombok expects (EnumName.CONSTANT handled earlier, or ClassName.class).
- Centralize valid annotation values with a dedicated annotation/class instead of field references.
Example fix
// before @Getter(AccessLevels.PUBLIC_FIELD_LEVEL) // after @Getter(AccessLevel.PUBLIC) // literal/enum constant, not an arbitrary static field reference
Defensive patterns
Strategy: validation
Validate before calling
if (/[A-Za-z_$][\w$]*\s*\.\s*[A-Z_][\w$]*/.test(annotationValueExpr) && !annotationValueExpr.trim().endsWith(".class")) throw new IllegalArgumentException("Annotation values must be literals, not field references: " + annotationValueExpr); Type guard
function isFieldReference(expr) { return /^[A-Za-z_$][\w$]*\.[A-Za-z_$][\w$]*$/.test(expr.trim()) && !expr.trim().endsWith(".class"); } Try / catch
try { V v = annotationValues.getValue("member"); } catch (AnnotationValueDecodeFail e) { log.error("Inline the constant literal instead of referencing a field"); } Prevention
- Never reference static fields inside annotation arguments.
- Keep a constants class for code, but inline values into annotations.
- Treat annotation values as literals-only by convention.
When it happens
Trigger: An annotation value in source is written as a field selection, e.g. @MyAnn(MyClass.SOME_STRING), and the guess reaches the final FieldSelect check in guessToType (i.e. it was not resolvable as a primitive literal, enum constant, or class literal earlier).
Common situations: Sharing constants across annotations via a constants class; after a refactor that replaced string literals with static final fields inside lombok annotation arguments.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- I can't make sense of this annotation value. Try using a…
- Expected a single value, but
- Can't translate to an enum of type
- Can't translate to a class object.
- Can't translate a to the expected
AI-assisted analysis of projectlombok/lombok@6d6a3e9fec (2026-09-07).
Data as JSON: /api/errors/fc6c323dca2a56d9.
Report an issue: GitHub.
Appendix: source
Thrown at src/core/lombok/core/AnnotationValues.java:366
"Can't translate " + fieldSel + " to an enum of type " + expected, pos);
}
}
if (expected == Class.class) {
if (guess instanceof ClassLiteral) try {
String classLit = ((ClassLiteral) guess).getClassName();
return Class.forName(toFQ(classLit));
} catch (ClassNotFoundException e) {
throw new AnnotationValueDecodeFail(v,
"Can't translate " + guess + " to a class object.", pos);
}
}
if (guess instanceof AnnotationValues) {
return ((AnnotationValues<?>) guess).getInstance();
}
if (guess instanceof FieldSelect) throw new AnnotationValueDecodeFail(v,
"You must use constant literals in lombok annotations; they cannot be references to (static) fields.", pos);
throw new AnnotationValueDecodeFail(v,
"Can't translate a " + guess.getClass() + " to the expected " + expected, pos);
}
/**
* Returns the raw expressions used for the provided {@code annotationMethodName}.
*
* You should use this method for annotation methods that return {@code Class} objects. Remember that
* class literals end in ".class" which you probably want to strip off.
*/
public List<String> getRawExpressions(String annotationMethodName) {
AnnotationValue v = values.get(annotationMethodName);
return v == null ? Collections.<String>emptyList() : v.raws;
}
/**View on GitHub (pinned to 6d6a3e9fec)