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

  1. Inline the literal value directly into the annotation (copy the constant's value).
  2. Keep the constant but only use it in non-annotation code; annotations must use literals.
  3. 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).
  4. 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

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


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)