chinabugotech/hutool · error · IllegalArgumentException

Bad number '{}{}' at: {}

Error message

Bad number '{}{}' at: {}

What it means

NumberChineseFormatter.chineseToNumber(String) parses Chinese numerals digit-by-digit. Each digit (零一二...九) must be followed by a unit (十百千万亿...). Two consecutive digits with no unit between them is illegal and throws IllegalArgumentException showing the offending pair and position.

Source

Thrown at hutool-core/src/main/java/cn/hutool/core/convert/NumberChineseFormatter.java:527

		// 节总和
		int section = 0;
		int number = 0;
		ChineseUnit unit = null;
		char c;
		for (int i = 0; i < length; i++) {
			c = chinese.charAt(i);
			final int num = chineseToNumber(c);
			if (num >= 0) {
				if (num == 0) {
					// 遇到零时节结束,权位失效,比如两万二零一十
					if (number > 0 && null != unit) {
						section += number * (unit.value / 10);
					}
					unit = null;
				} else if (number > 0) {
					// 多个数字同时出现,报错
					throw new IllegalArgumentException(StrUtil.format("Bad number '{}{}' at: {}", chinese.charAt(i - 1), c, i));
				}
				// 普通数字
				number = num;
			} else {
				unit = chineseToUnit(c);
				if (null == unit) {
					// 出现非法字符
					throw new IllegalArgumentException(StrUtil.format("Unknown unit '{}' at: {}", c, i));
				}

				//单位
				if (unit.secUnit) {
					// 节单位,按照节求和
					section = (section + number) * unit.value;
					result += section;
					section = 0;
				} else {
					// 非节单位,和单位前的单数字组合为值

View on GitHub (pinned to 8870454b2a)

Solutions

  1. Validate the input format before parsing: alternate digit and unit, allow a single trailing digit.
  2. Sanitize/correct malformed input (e.g. insert 十 between consecutive digits) before calling.
  3. Wrap the call in try/catch IllegalArgumentException and surface a user-facing error.

Example fix

// before
int n = NumberChineseFormatter.chineseToNumber(userInput);

// after - validate then parse
if (!userInput.matches("[零一二三四五六七八九][十百千万亿]*([零一二三四五六七八九][十百千万亿]*)*[零一二三四五六七八九]?")) {
    throw new IllegalArgumentException("Invalid chinese numeral: " + userInput);
}
int n = NumberChineseFormatter.chineseToNumber(userInput);
Defensive patterns

Strategy: validation

Validate before calling

// a digit must be followed by a unit (or be the last char)
if (chinese.matches(".*[零一二三四五六七八九][零一二三四五六七八九].*")) {
    throw new IllegalArgumentException("consecutive digits in chinese numeral: " + chinese);
}
NumberChineseFormatter.chineseToNumber(chinese);

Try / catch

try {
    return NumberChineseFormatter.chineseToNumber(s);
} catch (IllegalArgumentException e) {
    if (e.getMessage().startsWith("Bad number")) { /* show user-facing parse error */ }
    else throw e;
}

Prevention

When it happens

Trigger: Calling chineseToNumber with input like "一一", "二三" (two digits back-to-back), or any string where a digit follows another digit without an intervening unit.

Common situations: User-supplied Chinese numeral input; data-entry mistakes; concatenation of partial numerals without units.

Related errors


AI-assisted analysis of chinabugotech/hutool@8870454b2a (2026-08-14). Data as JSON: /api/errors/1e80351da2d6bc31. Report an issue: GitHub.