projectlombok/lombok · error · AnnotationValueDecodeFail
Can't translate a to the expected
Error message
Can't translate a ${guess.getClass()} to the expected ${expected} What it means
This is guessToType()'s catch-all: when a guess (the compiler's parsed representation of an annotation value) is of a node type lombok has no converter for — not a literal, FieldSelect, ClassLiteral, or nested AnnotationValues — it throws AnnotationValueDecodeFail reporting the guess's class and the expected type. It signals an unsupported/unexpected annotation value shape.
Solutions
- Simplify the annotation value to a plain literal (string, number, boolean, enum constant, or class literal).
- Remove any computed expressions from the annotation — Java requires constant expressions, lombok requires simple literals.
- Reproduce with a minimal annotation usage; if it persists on a valid literal, report a lombok bug with compiler version.
- Check JDK/Eclipse compatibility of your lombok version; upgrade lombok to match your compiler.
Example fix
// before @MyAnn(count = 1 + 1) // expression node unsupported // after @MyAnn(count = 2)
Defensive patterns
Strategy: validation
Validate before calling
Set<String> allowed = Set.of("literal", "fieldSelect", "classLiteral", "annotation"); if (!allowed.contains(guessKind)) throw new IllegalArgumentException("Unsupported annotation value shape: " + guessKind); Type guard
function isSupportedAnnotationValue(expr) { return /^("[^"]*"|'[^']*'|\d+|\d+\.\d+|true|false|[A-Z][\w$]*|[A-Za-z_$][\w$.]*\.class|\[[^\]]*\])$/.test(expr.trim()); } Try / catch
try { V v = annotationValues.getValue("member"); } catch (AnnotationValueDecodeFail e) { log.error("Unsupported annotation value shape; use a plain literal"); } Prevention
- Keep annotation values to simple compile-time literals.
- Avoid expressions and exotic AST shapes in annotation arguments.
- Pin a lombok version compatible with your JDK/IDE and upgrade together.
When it happens
Trigger: An annotation member receives a parsed expression whose AST node class does not match any branch in guessToType (e.g. complex expressions, binary operations, or compiler-specific nodes) — the final unconditional throw in guessToType.
Common situations: Writing expressions like 1 + 2 or string concatenation in annotation values; compiler/IDE-specific AST variants after a JDK or Eclipse version change; custom AST node types from other annotation processors interleaving with lombok.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 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.
- You must use constant literals in lombok annotations; they…
AI-assisted analysis of projectlombok/lombok@6d6a3e9fec (2026-09-07).
Data as JSON: /api/errors/eb79da58cfa0df0b.
Report an issue: GitHub.
Appendix: source
Thrown at src/core/lombok/core/AnnotationValues.java:369
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;
}
/**
* Returns the actual expressions used for the provided {@code annotationMethodName}.
*/
public List<Object> getActualExpressions(String annotationMethodName) {View on GitHub (pinned to 6d6a3e9fec)