theonedev/onedev · error · StringValueConversionException

Cannot convert '%s' to enum constant of type '%s'.

Error message

Cannot convert '%s' to enum constant of type '%s'.

What it means

Strings.toEnum converts a string value to an enum constant via Enum.valueOf(enumClass, value). If value is null, not a valid constant name, or (in newer JDKs) not an exact case match, the exception is wrapped in a StringValueConversionException with the message 'Cannot convert %s to enum constant of type %s'. The original failure (NullPointerException/IllegalArgumentException) is chained as the cause.

Source

Thrown at server-core/src/main/java/org/apache/wicket/util/string/Strings.java:1581

	 *
	 * @param value
	 *            the value to convert to an enum value
	 * @param enumClass
	 *            the enum type
	 * @return an enum value
	 */
	public static <T extends Enum<T>> T toEnum(final CharSequence value, final Class<T> enumClass)
	{
		Args.notNull(enumClass, "enumClass");
		Args.notNull(value, "value");

		try
		{
			return Enum.valueOf(enumClass, value.toString());
		}
		catch (Exception e)
		{
			throw new StringValueConversionException(
					String.format("Cannot convert '%s' to enum constant of type '%s'.", value, enumClass), e);
		}
	}

	/**
	 * Returns the original string if this one is not empty (i.e. {@link #isEmpty(CharSequence)} returns false), 
	 * otherwise the default one is returned. The default string might be itself an empty one.
	 * 
	 * @param originalString
	 * 				the original sting value
	 * @param defaultValue
	 * 				the default string to return if the original is empty
	 * @return 	the original string value if not empty, the default one otherwise
	 */
	public static String defaultIfEmpty(String originalString, String defaultValue)
	{
		return isEmpty(originalString) ? defaultValue : originalString;		
	}

View on GitHub (pinned to d44925c47c)

Solutions

  1. Make the input exactly match a constant name (trim, then correct the case)
  2. Use a case-insensitive lookup: Arrays.stream(EnumClass.values()).filter(e -> e.name().equalsIgnoreCase(v.trim())).findFirst()
  3. Handle the absent value before conversion to avoid the NullPointerException cause
  4. Update stored config/data to use current constant names after enum changes

Example fix

// before
Mode m = Strings.toEnum(Mode.class, cfg.get("mode")); // "debug" -> throw
// after
String v = cfg.get("mode");
Mode m = Mode.valueOf(v == null ? "DEBUG" : v.trim().toUpperCase(Locale.ROOT));
Defensive patterns

Strategy: validation

Validate before calling

// Java
static <T extends Enum<T>> T safeToEnum(Class<T> type, String v, T fallback) {
    if (v == null) return fallback;
    for (T e : type.getEnumConstants()) {
        if (e.name().equalsIgnoreCase(v.trim())) return e;
    }
    return fallback;
}

Try / catch

try {
    mode = Strings.toEnum(Mode.class, value);
} catch (StringValueConversionException e) {
    log.warn("Unknown enum value '{}' for type {}", value, Mode.class.getSimpleName());
    mode = Mode.DEFAULT;
}

Prevention

When it happens

Trigger: Calling Strings.toEnum(MyEnum.class, s) with a string that does not exactly match an enum constant name — wrong case, extra whitespace, renamed constants, or a null/absent value.

Common situations: Config values written in lowercase ('debug' vs 'DEBUG'); enum constants renamed after a Wicket/dependency upgrade; persisted old values no longer present in the enum; whitespace from property files.

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 theonedev/onedev@d44925c47c (2026-09-06). Data as JSON: /api/errors/b91d37dbcc31672c. Report an issue: GitHub.