skylot/jadx · error · JadxArgsValidateException

'{}' is unknown, possible values are: {}

Error message

'{}' is unknown, possible values are: {}

What it means

Thrown by FieldNodeAdapter.read while deserializing a cached code annotation: it reads the declaring class name and short id that were persisted, then calls root.resolveRawClass(cls). If the class is absent from the current project the lookup returns null and the adapter aborts. It means the on-disk cache references a class that the loaded APK/jadx state no longer contains.

Source

Thrown at jadx-cli/src/main/java/jadx/cli/JadxCLIArgs.java:1066

			super(CallGraphSaveMode::valueOf, CallGraphSaveMode::values);
		}
	}

	public abstract static class BaseEnumConverter<E extends Enum<E>> implements IStringConverter<E> {
		private final Function<String, E> parse;
		private final Supplier<E[]> values;

		public BaseEnumConverter(Function<String, E> parse, Supplier<E[]> values) {
			this.parse = parse;
			this.values = values;
		}

		@Override
		public E convert(String value) {
			try {
				return parse.apply(stringAsEnumName(value));
			} catch (Exception e) {
				throw new JadxArgsValidateException(
						'\'' + value + "' is unknown, possible values are: " + enumValuesString(values.get()));
			}
		}
	}

	public static String enumValuesString(Enum<?>[] values) {
		return Stream.of(values)
				.map(v -> v.name().replace('_', '-').toLowerCase(Locale.ROOT))
				.collect(Collectors.joining(", "));
	}

	private static String stringAsEnumName(String value) {
		// inverse of enumValuesString conversion
		return value.replace('-', '_').toUpperCase(Locale.ROOT);
	}
}

View on GitHub (pinned to e738a26571)

Solutions

  1. Delete the jadx cache directory for the project and let it rebuild (fastest fix).
  2. Ensure the APK opened is byte-identical to the one that produced the cache; if not, invalidate the cache.
  3. Upgrade jadx; newer versions catch this and invalidate the cache instead of crashing.
  4. Verify the APK path did not change under the same cache key.

Example fix

// before
ClassNode clsNode = root.resolveRawClass(cls);
if (clsNode == null) {
    throw new RuntimeException("Class not found: " + cls);
}

// after
ClassNode clsNode = root.resolveRawClass(cls);
if (clsNode == null) {
    // stale cache entry: signal caller to discard the on-disk cache and rebuild
    throw new CacheInvalidatedException("Class not found: " + cls);
}
Defensive patterns

Strategy: validation

Validate before calling

// Before deserializing a cached annotation referencing a class, confirm it still resolves:
ClassNode clsNode = root.resolveRawClass(cls);
if (clsNode == null) {
    // input changed since cache write: invalidate and rebuild rather than throw
    invalidateCache();
    return;
}

Try / catch

// Cache load layer: catch and discard the whole cache on a stale reference
try {
    return adapter.read(in);
} catch (RuntimeException e) {
    if (e.getMessage() != null && e.getMessage().startsWith("Class not found")) {
        LOG.warn("Stale cache, rebuilding: {}", e.getMessage());
        cacheDir.delete();
        return null;
    }
    throw e;
}

Prevention

When it happens

Trigger: Loading a persisted code-annotation cache (the per-project disk cache written by jadx-gui) whose entries were written against a different input. resolveRawClass fails because the APK was swapped, rebuilt, or proguard-mapped differently since the cache was written.

Common situations: Re-opening a project after the APK was updated/re-signed/obfuscated differently; switching jadx versions that resolve classes differently; the cache directory surviving an input change; loading a cache written on another machine against a different APK.

Related errors


AI-assisted analysis of skylot/jadx@e738a26571 (2026-08-14). Data as JSON: /api/errors/2ff444d8a5881827. Report an issue: GitHub.