apache/dubbo · error · IllegalArgumentException

CAN NOT convert String(%s) to char! when convert String to c

Error message

CAN NOT convert String(%s) to char! when convert String to char, the String MUST only 1 char.

What it means

Thrown by CompatibleTypeUtils.compatibleTypeConvert when converting a String to char or java.lang.Character but the string's length is not exactly 1. A char holds a single Unicode character; a multi-char or empty string cannot be mapped to one, so the conversion is rejected rather than guessing (e.g. taking charAt(0) silently).

Source

Thrown at dubbo-common/src/main/java/org/apache/dubbo/common/utils/CompatibleTypeUtils.java:66

     * <p>
     * Supported compatible type conversions include (primary types and corresponding wrappers are not listed):
     * <ul>
     * <li> String -> char, enum, Date
     * <li> byte, short, int, long -> byte, short, int, long
     * <li> float, double -> float, double
     * </ul>
     */
    @SuppressWarnings({"unchecked", "rawtypes"})
    public static Object compatibleTypeConvert(Object value, Class<?> type) {
        if (value == null || type == null || type.isAssignableFrom(value.getClass())) {
            return value;
        }

        if (value instanceof String) {
            String string = (String) value;
            if (char.class.equals(type) || Character.class.equals(type)) {
                if (string.length() != 1) {
                    throw new IllegalArgumentException(String.format(
                            "CAN NOT convert String(%s) to char!"
                                    + " when convert String to char, the String MUST only 1 char.",
                            string));
                }
                return string.charAt(0);
            }
            if (type.isEnum()) {
                return Enum.valueOf((Class<Enum>) type, string);
            }
            if (type == BigInteger.class) {
                return new BigInteger(string);
            }
            if (type == BigDecimal.class) {
                return new BigDecimal(string);
            }
            if (type == Short.class || type == short.class) {
                return new Short(string);
            }

View on GitHub (pinned to 3a3043227f)

Solutions

  1. Send exactly one character for char/Character parameters; trim or validate the source string to length 1.
  2. If the field should hold longer text, change its type to String on both sides.
  3. Pre-validate: if (stringValue == null || stringValue.length() != 1) reject before the RPC/config binding.

Example fix

// before
Object c = CompatibleTypeUtils.compatibleTypeConvert("abc", char.class); // throws

// after
Object c = CompatibleTypeUtils.compatibleTypeConvert("a", char.class);
// or change the target type to String if multi-char is intended
Defensive patterns

Strategy: validation

Validate before calling

String s = /* ... */;
if (s == null || s.length() != 1) {
    throw new IllegalArgumentException("char conversion requires a single-character string: " + s);
}
CompatibleTypeUtils.compatibleTypeConvert(s, char.class);

Type guard

static boolean isSingleChar(String s) {
    return s != null && s.length() == 1;
}

Prevention

When it happens

Trigger: compatibleTypeConvert(stringValue, char.class) or (stringValue, Character.class) where stringValue.length() != 1 — e.g. "", "ab", "abc". The method is used by Dubbo's RPC parameter deserialization when a String-typed value must populate a char field/param.

Common situations: An RPC method declares a char/Character parameter but the caller sends a longer string (or empty); a config value mapped to a char field carries multiple characters; JSON/form deserialization of a char from a free-text value. Mismatch between the producer's string and the consumer's char type.

Related errors


AI-assisted analysis of apache/dubbo@3a3043227f (2026-08-14). Data as JSON: /api/errors/6c6025155419cafc. Report an issue: GitHub.