{"record":{"id":"d806e14178075cbc","repo":"pentaho/pentaho-kettle","slug":"can-t-create-object","errorCode":null,"errorMessage":"Can't create object ","messagePattern":"Can't create object ","errorType":"exception","errorClass":"KettleException","httpStatus":null,"severity":"error","filePath":"engine/src/main/java/org/pentaho/di/core/injection/bean/BeanInjector.java","lineNumber":340,"sourceCode":"          throw new KettleException( \"No field or setter defined for \" + root.getClass() );\n        }\n      }\n    }\n    return true;\n  }\n\n  private Object createObject( Class<?> clazz, Object root ) throws KettleException {\n    try {\n      // Object can be inner of metadata class. In this case constructor will require parameter\n      for ( Constructor<?> c : clazz.getConstructors() ) {\n        if ( c.getParameterTypes().length == 0 ) {\n          return clazz.newInstance();\n        } else if ( c.getParameterTypes().length == 1 && c.getParameterTypes()[0].isAssignableFrom( info.clazz ) ) {\n          return c.newInstance( root );\n        }\n      }\n    } catch ( Throwable ex ) {\n      throw new KettleException( \"Can't create object \" + clazz, ex );\n    }\n    throw new KettleException( \"Constructor not found for \" + clazz );\n  }\n\n  private Object extendArray( BeanLevelInfo s, Object obj, int newSize ) throws Exception {\n    Object existArray = s.field.get( obj );\n    if ( existArray == null ) {\n      existArray = Array.newInstance( s.leafClass, newSize );\n      s.field.set( obj, existArray );\n    }\n    int existSize = Array.getLength( existArray );\n    if ( existSize < newSize ) {\n      Object newSized = Array.newInstance( s.leafClass, newSize );\n      System.arraycopy( existArray, 0, newSized, 0, existSize );\n      existArray = newSized;\n      s.field.set( obj, existArray );\n    }\n","sourceCodeStart":322,"sourceCodeEnd":358,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/engine/src/main/java/org/pentaho/di/core/injection/bean/BeanInjector.java#L322-L358","documentation":"BeanInjector.createObject() uses reflection to instantiate a nested object along the injection path, either via a no-arg constructor or a single-arg constructor taking the root. Any reflective failure (no accessible constructor, instantiation exception) is wrapped in this KettleException.","triggerScenarios":"setProperty encounters a path level whose class lacks a usable no-arg constructor or a constructor accepting the root object; constructor throws during newInstance.","commonSituations":"Nested bean without a default constructor; abstract class or interface in the injection path; constructor throws IllegalArgumentException on root.","solutions":["Add a public no-arg constructor to the nested class","Add a constructor taking the root bean type if contextual construction is needed","Make the injected property type concrete (not abstract/interface)","Catch-and-log to see the wrapped cause for why newInstance failed"],"exampleFix":"// before\nclass Child { Child(Root r, int extra){...} } // no matching ctor\n// after\nclass Child { public Child(){} public Child(Root r){...} }","handlingStrategy":"try-catch","validationCode":"// Verify the nested class has a usable constructor before injecting\nClass<?> c = nestedPropertyType;\nboolean ok = Arrays.stream(c.getConstructors()).anyMatch(ctor ->\n  ctor.getParameterCount() == 0\n  || (ctor.getParameterCount() == 1 && ctor.getParameterTypes()[0].isAssignableFrom(rootClass)));\nif (!ok) throw new IllegalStateException(\"No injectable constructor on \" + c.getName());","typeGuard":"static boolean instantiableForInjection(Class<?> c, Class<?> root) {\n  if (c.isInterface() || Modifier.isAbstract(c.getModifiers())) return false;\n  try { c.getDeclaredConstructor(); return true; }\n  catch (NoSuchMethodException e) {\n    for (Constructor<?> k : c.getConstructors())\n      if (k.getParameterCount() == 1 && k.getParameterTypes()[0].isAssignableFrom(root)) return true;\n    return false;\n  }\n}","tryCatchPattern":"try {\n  injector.injectValue(bean, path, value);\n} catch (KettleException e) {\n  if (e.getMessage().startsWith(\"Can't create object\")) {\n    log.error(\"Failed to instantiate nested bean; cause: \", e.getCause());\n  } else throw e;\n}","preventionTips":["Give every nested injection bean a public no-arg constructor","Avoid abstract/interface types on injection path properties","Keep constructors side-effect-free so newInstance cannot throw"],"tags":["reflection","constructor","bean-injection"],"backgroundTag":"invalid-constructor-argument","analyzedSha":"f3058517a153da500bf4551f46d79b91bf8ec552","analyzedAt":"2026-09-13T14:04:16.340Z","contentChangedAt":"2026-09-13T14:04:16.340Z","schemaVersion":2},"datasetVersion":"2026-09-20T23:17:15.980Z"}