chinabugotech/hutool · error · ConvertException

Unsupported source type: [{}] to [{}]

Error message

Unsupported source type: [{}] to [{}]

What it means

Thrown by RecordConverter.convert() when the source value is not a ValueProvider, a Map, or a 'readable bean' (as decided by BeanUtil.isReadableBean). Record construction requires property-by-property source data, so scalar values like Strings, Numbers, or arbitrary objects that fail the readable-bean check cannot be used to build a Record.

Source

Thrown at hutool-core/src/main/java/cn/hutool/core/convert/impl/RecordConverter.java:46

	}

	@SuppressWarnings("unchecked")
	@Override
	public Object convert(Object value, Object defaultValue) throws IllegalArgumentException {
		ValueProvider<String> valueProvider = null;
		if (value instanceof ValueProvider) {
			valueProvider = (ValueProvider<String>) value;
		} else if (value instanceof Map) {
			valueProvider = new MapValueProvider((Map<String, ?>) value);
		} else if (BeanUtil.isReadableBean(value.getClass())) {
			valueProvider = new BeanValueProvider(value, false, false);
		}

		if (null != valueProvider) {
			return RecordUtil.newInstance(recordClass, valueProvider);
		}

		throw new ConvertException("Unsupported source type: [{}] to [{}]", value.getClass(), recordClass);
	}
}

View on GitHub (pinned to 8870454b2a)

Solutions

  1. Convert the source to a Map (e.g., Map<String,Object>) before targeting a Record type.
  2. If the source is a POJO, ensure it has public getters or use BeanUtil.toBean() which may handle it through a different path.
  3. Wrap the source in a ValueProvider<String> implementation if you need custom property resolution.
  4. Validate that value.getClass() passes BeanUtil.isReadableBean(value.getClass()) before attempting the Record conversion.

Example fix

// before
Convert.convert(MyRecord.class, "{\"a\":1}"); // String, not a Map -> throws

// after
Map<String,Object> map = JSONUtil.toBean("{\"a\":1}", Map.class);
MyRecord rec = Convert.convert(MyRecord.class, map);
Defensive patterns

Strategy: type-guard

Validate before calling

if (!(value instanceof Map) && !(value instanceof ValueProvider)
    && !BeanUtil.isReadableBean(value.getClass())) {
    throw new IllegalArgumentException("Value must be a Map, ValueProvider, or readable bean");
}
Convert.convert(recordClass, value);

Type guard

static boolean canConvertToRecord(Object value) {
    return value instanceof Map || value instanceof ValueProvider
        || BeanUtil.isReadableBean(value.getClass());
}

Try / catch

try {
    return Convert.convert(recordClass, value);
} catch (ConvertException e) {
    if (e.getMessage().contains("Unsupported source type")) {
        Map<String,Object> map = BeanUtil.beanToMap(value);
        return Convert.convert(recordClass, map);
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling Convert.convert(MyRecord.class, "someString") or Convert.convert(MyRecord.class, 42). Passing a POJO with no readable getters (all fields private with no accessors), causing BeanUtil.isReadableBean to return false. Passing an array, Collection, or enum value as the source.

Common situations: Deserializing JSON or form data into a Java Record where the JSON deserializer produced a scalar instead of a Map. Attempting to convert a primitive wrapper or String into a multi-field Record. POJOs with only private fields and Lombok @FieldNameConstants or @Builder but no getters, failing isReadableBean.

Related errors


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