{"record":{"id":"a9f102406ed54a9e","repo":"apache/pulsar","slug":"cannot-convert-from-to-requested-converter-does","errorCode":null,"errorMessage":"Cannot convert from  to . Requested converter does not exist.","messagePattern":"Cannot convert from  to \\. Requested converter does not exist\\.","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"pulsar-common/src/main/java/org/apache/pulsar/common/util/FieldParser.java","lineNumber":119,"sourceCode":"            // Converting string to enum\n            DeserializationConfig deserializationConfig =\n                    ObjectMapperFactory.getMapper().getObjectMapper().getDeserializationConfig();\n            // No replacement API available in Jackson 2.x\n            AnnotatedClass annotatedEnum = AnnotatedClassResolver.resolve(\n                    deserializationConfig,\n                    deserializationConfig.getTypeFactory().constructType(to),\n                    deserializationConfig\n            );\n            EnumResolver r = EnumResolver.constructUsingToString(deserializationConfig, annotatedEnum);\n            T value = (T) r.findEnum((String) from);\n            if (value == null) {\n                throw new RuntimeException(\"Invalid value '\" + from + \"' for enum \" + to);\n            }\n            return value;\n        }\n\n        if (converter == null) {\n            throw new UnsupportedOperationException(\"Cannot convert from \" + from.getClass().getName() + \" to \"\n                    + to.getName() + \". Requested converter does not exist.\");\n        }\n\n        // Convert the value.\n        try {\n            Object val = converter.invoke(to, from);\n            return to.cast(val);\n        } catch (Exception e) {\n            throw new RuntimeException(\"Cannot convert from \" + from.getClass().getName() + \" to \" + to.getName()\n                    + \". Conversion failed with \" + e.getMessage(), e);\n        }\n    }\n\n    /**\n     * Update given Object attribute by reading it from provided map properties.\n     *\n     * @param properties\n     *            which key-value pair of properties to assign those values to given object","sourceCodeStart":101,"sourceCodeEnd":137,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-common/src/main/java/org/apache/pulsar/common/util/FieldParser.java#L101-L137","documentation":"FieldParser.convert() only supports a fixed set of source->target conversions (String<->Integer/Long/Double/Float/Boolean, direct casts, and String->enum). If the source object's type and target type do not match any registered converter, it throws UnsupportedOperationException. It exists to fail fast instead of silently returning a wrong-typed value during reflective config-field population.","triggerScenarios":"Calling FieldParser.convert(obj, Target.class) where obj's runtime class has no registered converter, e.g. convert(42L, Integer.class), convert(\"abc\", LocalDate.class), or a List<String> field whose element type is a non-String/number type reached via stringToList/stringToSet/stringToMap.","commonSituations":"Populating a Pulsar config object (FieldParser.update) from a properties map where a field is of an unsupported type (Instant, custom POJO, Map with non-primitive values); passing a non-String source to convert(); typos in generic type parameters on config fields.","solutions":["Change the field type (or the source value) to one of the supported types: String, Integer, Long, Double, Float, Boolean, enum, or collections thereof.","If the source is a String but the target is unsupported, pre-convert the value yourself before calling convert/update.","Add a public static converter method with the signature Target converter(Source) to a helper class if you control the code, or extend FieldParser with a new converter method pair (e.g. stringToLocalDate).","Check the exception message: it names the exact source and target class names that have no converter registered."],"exampleFix":"// before\nDuration d = FieldParser.convert(\"5000\", Duration.class); // UnsupportedOperationException\n// after\nlong millis = FieldParser.convert(\"5000\", Long.class);\nDuration d = Duration.ofMillis(millis);","handlingStrategy":"validation","validationCode":"private static final Set<Class<?>> SUPPORTED = Set.of(String.class, Integer.class, Long.class, Double.class, Float.class, Boolean.class);\nstatic <T> void checkConvertible(Object from, Class<T> to) {\n    if (from != null && !to.isAssignableFrom(from.getClass())\n            && !SUPPORTED.contains(from.getClass()) && !to.isEnum()) {\n        throw new IllegalArgumentException(\"no FieldParser converter for \"\n                + from.getClass().getName() + \" -> \" + to.getName());\n    }\n}","typeGuard":"static boolean isSimpleConvertibleType(Class<?> c) {\n    return String.class.equals(c) || Number.class.isAssignableFrom(c)\n            || Boolean.class.equals(c) || (c.isEnum() && c.getSuperclass() != null && c.getSuperclass().isEnum());\n}","tryCatchPattern":"try {\n    T v = FieldParser.convert(from, to);\n} catch (UnsupportedOperationException e) {\n    // no registered converter for this type pair — handle/prefill manually\n    log.warn(\"unsupported conversion\", e);\n}","preventionTips":["Restrict config POJO fields to String, primitives/wrappers, enums, and collections of those","Never call convert() with non-String sources for numeric targets","Add a unit test that runs FieldParser.update() over every field of your config class","Check the CONVERTERS-supported types before introducing exotic field types"],"tags":["reflection","type-conversion","configuration"],"backgroundTag":"unsupported-type-conversion","analyzedSha":"820761864ed8e2a7d2e52dd9763ad2ae117c1395","analyzedAt":"2026-09-06T00:14:20.138Z","contentChangedAt":"2026-09-06T00:14:20.138Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}