projectlombok/lombok · error · IllegalArgumentException

Invalid null annotation library. Valid options: none…

Error message

Invalid null annotation library. Valid options: none, javax, jakarta, eclipse, jetbrains, netbeans, androidx, android.support, checkerframework, findbugs, spring, jml, jspecify or CUSTOM:[TYPE_USE:]nonnull.annotation.type:nullable.annotation.type

What it means

NullAnnotationLibrary.valueOf resolves the 'lombok.copyableAnnotations'-style null annotation config key (checker-quality nullity annotations) to a library. Values not matching a built-in key and not starting with 'custom:' are rejected with a list of valid options.

Solutions

  1. Use one of the listed keys exactly: none, javax, jakarta, eclipse, jetbrains, netbeans, androidx, android.support, checkerframework, findbugs, spring, jml, jspecify.
  2. For a non-bundled library, use the custom: syntax: CUSTOM:[TYPE_USE:]nonnull.annotation.type:nullable.annotation.type.
  3. Check spelling and casing; keys are matched case-insensitively on the canonical form but must otherwise be exact.

Example fix

// before (lombok.config)
lombok.nullable.annotations = javax.validation
// after
lombok.nullable.annotations = javax
Defensive patterns

Strategy: validation

Validate before calling

java.util.Set<String> VALID = java.util.Set.of("none","javax","jakarta","eclipse","jetbrains","netbeans","androidx","android.support","checkerframework","findbugs","spring","jml","jspecify");
boolean isValidNullAnnotationLibrary(String v) {
  String lv = v.trim().toLowerCase();
  return VALID.contains(lv) || lv.startsWith("custom:");
}

Try / catch

try {
  NullAnnotationLibrary lib = NullAnnotationLibrary.valueOf(cfgValue);
} catch (IllegalArgumentException e) {
  // fall back to a built-in key such as "javax"
}

Prevention

When it happens

Trigger: Setting the null-annotation config value to a misspelled or unsupported library name, wrong casing (the comparison uses a canonical lowercase 'ci'), or an empty/unknown string.

Common situations: Typing 'javax.validation' or 'JSR305' instead of a listed key; using an old key name removed from ALL_AVAILABLE; capitalization mismatches in lombok.config.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


AI-assisted analysis of projectlombok/lombok@6d6a3e9fec (2026-09-07). Data as JSON: /api/errors/3817af3a5d98e09c. Report an issue: GitHub.

Appendix: source

Thrown at src/core/lombok/core/configuration/NullAnnotationLibrary.java:125

	
	public static String description() {
		return "nullity-annotation-library";
	}
	
	public static String exampleValue() {
		return EXAMPLE_VALUE;
	}
	
	public static NullAnnotationLibrary valueOf(String in) {
		String ci = in == null ? "" : in.toLowerCase();
		if (ci.length() == 0) return NONE;
		for (NullAnnotationLibrary nal : ALL_AVAILABLE) if (nal.key.equals(ci)) return nal;
		if (!ci.startsWith("custom:")) {
			StringBuilder out = new StringBuilder("Invalid null annotation library. Valid options: ");
			for (NullAnnotationLibrary nal : ALL_AVAILABLE) out.append(nal.key).append(", ");
			out.setLength(out.length() - 2);
			out.append(" or CUSTOM:[TYPE_USE:]nonnull.annotation.type:nullable.annotation.type");
			throw new IllegalArgumentException(out.toString());
		}
		boolean typeUse = ci.startsWith("custom:type_use:");
		int start = typeUse ? 16 : 7;
		int split = ci.indexOf(':', start);
		if (split == -1) {
			String nonNullAnnotation = in.substring(start);
			return custom(verifyTypeName(nonNullAnnotation), null, typeUse);
		}
		String nonNullAnnotation = in.substring(start, split);
		String nullableAnnotation = in.substring(split + 1);
		return custom(verifyTypeName(nonNullAnnotation), verifyTypeName(nullableAnnotation), typeUse);
	}
	
	private static final String MSG = "Not an identifier (provide a fully qualified type for custom: nullity annotations): ";
	private static String verifyTypeName(String fqn) {
		boolean atStart = true;
		for (int i = 0; i < fqn.length(); i++) {
			char c = fqn.charAt(i);

View on GitHub (pinned to 6d6a3e9fec)