{"record":{"id":"adb5e9d503a1d3a9","repo":"flowable/flowable-engine","slug":"typeconverter-clazz-could-not-be-instantiated","errorCode":null,"errorMessage":"TypeConverter ${clazz} could not be instantiated","messagePattern":"TypeConverter (.+?) could not be instantiated","errorType":"exception","errorClass":"ELException","httpStatus":null,"severity":"error","filePath":"modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/de/odysseus/el/ExpressionFactoryImpl.java","lineNumber":372,"sourceCode":"\n\t\treturn new TreeStore(builder, cache);\n\t}\n\n\t/**\n\t * Create the factory's type converter. This implementation takes the\n\t * <code>de.odysseus.el.misc.TypeConverter</code> property as the name of a class implementing\n\t * the <code>de.odysseus.el.misc.TypeConverter</code> interface. If the property is not set, the\n\t * default converter (<code>TypeConverter.DEFAULT</code>) is used.\n\t */\n\tprotected TypeConverter createTypeConverter(Properties properties) {\n\t\tClass<?> clazz = load(TypeConverter.class, properties);\n\t\tif (clazz == null) {\n\t\t\treturn TypeConverter.DEFAULT;\n\t\t}\n\t\ttry {\n\t\t\treturn TypeConverter.class.cast(clazz.newInstance());\n\t\t} catch (Exception e) {\n\t\t\tthrow new ELException(\"TypeConverter \" + clazz + \" could not be instantiated\", e);\n\t\t}\n\t}\n\n\t/**\n\t * Create the factory's builder. This implementation takes the\n\t * <code>de.odysseus.el.tree.TreeBuilder</code> property as a name of a class implementing the\n\t * <code>de.odysseus.el.tree.TreeBuilder</code> interface. If the property is not set, a plain\n\t * <code>de.odysseus.el.tree.impl.Builder</code> is used. If the configured class is a subclass\n\t * of <code>de.odysseus.el.tree.impl.Builder</code> and which provides a constructor taking an\n\t * array of <code>Builder.Feature</code>, this constructor will be invoked. Otherwise, the\n\t * default constructor will be used.\n\t */\n\tprotected TreeBuilder createTreeBuilder(Properties properties, Feature... features) {\n\t\tClass<?> clazz = load(TreeBuilder.class, properties);\n\t\tif (clazz == null) {\n\t\t\treturn createDefaultTreeBuilder(features);\n\t\t}\n\t\ttry {","sourceCodeStart":354,"sourceCodeEnd":390,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/de/odysseus/el/ExpressionFactoryImpl.java#L354-L390","documentation":"createTypeConverter() instantiates the TypeConverter implementation named by the PROP_TYPE_CONVERTER property via reflection (clazz.newInstance()). Any failure — no public no-arg constructor, abstract class, wrong type, or constructor exception — is wrapped as ELException 'TypeConverter X could not be instantiated'.","triggerScenarios":"ExpressionFactoryImpl construction with a TypeConverter property naming a class that lacks a public no-arg constructor, is abstract/interface, throws in its constructor, or does not extend TypeConverter (then ClassCastException in cast).","commonSituations":"Pointing the property at a custom converter with only parameterized constructors; typo causing the wrong class to be named; converter class present but initializing state in constructor that fails (e.g. missing Spring context).","solutions":["Give the configured TypeConverter implementation a public no-argument constructor","Verify the class extends/implements TypeConverter (so the cast succeeds)","Confirm the class is concrete (not abstract/interface) and its constructor does not throw","Remove the property to use TypeConverter.DEFAULT"],"exampleFix":"// before\npublic class MyConverter extends TypeConverterImpl {\n    public MyConverter(String locale) { ... }\n}\n\n// after\npublic class MyConverter extends TypeConverterImpl {\n    public MyConverter() { ... }\n}","handlingStrategy":"validation","validationCode":"Class<?> c = Class.forName(\"com.acme.MyConverter\");\nif (!org.flowable.common.engine.impl.de.odysseus.el.TypeConverter.class.isAssignableFrom(c)\n    || java.lang.reflect.Modifier.isAbstract(c.getModifiers())\n    || c.getConstructors().length == 0 || java.util.Arrays.stream(c.getConstructors()).noneMatch(k -> k.getParameterCount() == 0)) {\n    throw new IllegalStateException(\"TypeConverter must be concrete with a public no-arg constructor\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    ExpressionFactory factory = new ExpressionFactoryImpl(props);\n} catch (ELException e) {\n    if (e.getMessage().contains(\"TypeConverter\") && e.getMessage().contains(\"could not be instantiated\")) {\n        log.error(\"Check constructor/TypeConverter contract of configured class\", e);\n    }\n    throw e;\n}","preventionTips":["Give custom converters a public no-arg constructor","Keep converters free of environment-dependent constructor logic","Add a reflective contract test for any class named in engine properties"],"tags":["reflection","el","configuration","instantiation","flowable"],"backgroundTag":"invalid-constructor-argument","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}