projectlombok/lombok · error · AnnotationValueDecodeFail
I can't make sense of this annotation value. Try using a…
Error message
I can't make sense of this annotation value. Try using a fully qualified literal.
What it means
AnnotationValues.getAsStringList() decodes annotation string-array members from the compiler's parse tree. When a value guess cannot be resolved to a String by guessToType() and there are multiple guesses (so no single-value default fallback applies), lombok throws AnnotationValueDecodeFail asking the user to write a fully qualified literal. This is lombok's way of rejecting annotation values it cannot statically interpret.
Solutions
- Replace the annotation value element with a plain string literal or fully qualified literal (e.g. fully spell out package.Class instead of an import-dependent select).
- Remove references to static fields/constants from the annotation value; Java annotations require compile-time constant literals.
- If a default exists for the method, use the single-value form so lombok can fall back to the default instead of throwing.
- Check for typos in the class/field name so guessToType can resolve it.
- Rebuild cleanly; stale incremental compilation state can leave guesses unresolved.
Example fix
// before
@Getter(value = {MyConstants.FOO, MyConstants.BAR})
// after
@Getter(value = {"foo", "bar"}) Defensive patterns
Strategy: validation
Validate before calling
function isPlainStringList(vals) { return Array.isArray(vals) && vals.every(v => typeof v === 'string' && !/[A-Za-z_$][\w$]*\s*\.[\w$]+/.test(v)); }
if (!isPlainStringList(myAnnotationValues)) throw new Error('Use plain string literals in the annotation'); Type guard
function isStringLiteral(v) { return typeof v === 'string'; } Try / catch
try { List<String> l = annotationValues.getAsStringList("value"); } catch (AnnotationValueDecodeFail e) { log.error("Bad annotation value at index " + e.idx + ": use a fully qualified literal"); } Prevention
- Use plain string literals, not static-field references, in lombok annotation values.
- Fully qualify class names in annotation string arrays.
- Rebuild after renaming constants referenced anywhere near annotations.
- Keep annotation usage minimal and literal-first.
When it happens
Trigger: A lombok annotation method expecting a String list receives an element that guessToType() cannot coerce to String (e.g. a FieldSelect referencing a field or an unresolvable select), and valueGuesses.size() > 1 so the getDefaultIf fallback path is skipped.
Common situations: Writing an annotation like @Getter(onMethod_=...) or a config annotation whose string array elements use non-literal references (e.g. SomeClass.CONSTANT) or typos in class references that fail qualification; also occurs after IDE refactors rename constants referenced from annotations.
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
- Can't translate to an enum of type
- Expected a single value, but
- Can't translate to a class object.
- You must use constant literals in lombok annotations; they…
- Can't translate a to the expected
AI-assisted analysis of projectlombok/lombok@6d6a3e9fec (2026-09-07).
Data as JSON: /api/errors/c2361bfd1468d6cb.
Report an issue: GitHub.
Appendix: source
Thrown at src/core/lombok/core/AnnotationValues.java:181
public List<String> getAsStringList(String methodName) {
AnnotationValue v = values.get(methodName);
if (v == null) {
String[] s = getDefaultIf(methodName, new String[0]);
return Collections.unmodifiableList(Arrays.asList(s));
}
List<String> out = new ArrayList<String>(v.valueGuesses.size());
int idx = 0;
for (Object guess : v.valueGuesses) {
Object result = guess == null ? null : guessToType(guess, String.class, v, idx);
if (result == null) {
if (v.valueGuesses.size() == 1) {
String[] s = getDefaultIf(methodName, new String[0]);
return Collections.unmodifiableList(Arrays.asList(s));
}
throw new AnnotationValueDecodeFail(v,
"I can't make sense of this annotation value. Try using a fully qualified literal.", idx);
}
out.add((String) result);
idx++;
}
return Collections.unmodifiableList(out);
}
public String getAsString(String methodName) {
AnnotationValue v = values.get(methodName);
if (v == null || v.valueGuesses.size() != 1) {
return getDefaultIf(methodName, "");
}
Object guess = guessToType(v.valueGuesses.get(0), String.class, v, 0);
if (guess instanceof String) return (String) guess;
return getDefaultIf(methodName, "");View on GitHub (pinned to 6d6a3e9fec)