{"record":{"id":"d2b7ef7435f91445","repo":"pentaho/pentaho-kettle","slug":"unable-to-instantiate-object-for-spoondelegateregistry","errorCode":null,"errorMessage":"Unable to instantiate object for ","messagePattern":"Unable to instantiate object for ","errorType":"exception","errorClass":"InstanceCreationException","httpStatus":null,"severity":"error","filePath":"ui/src/main/java/org/pentaho/di/ui/spoon/delegates/SpoonDelegateRegistry.java","lineNumber":74,"sourceCode":"\n  public SpoonDelegate constructSpoonJobDelegate( Spoon spoon ) throws InstanceCreationException {\n    try {\n      if ( jobDelegateClass == null ) {\n        Constructor<?> constructor = DEFAULT_SPOONJOBDELEGATE_CLASS.getConstructor( Spoon.class );\n        if ( constructor != null ) {\n          return (SpoonDelegate) constructor.newInstance( spoon );\n        } else {\n          throw new InstanceCreationException( \"Unable to get the constructor for \" + jobDelegateClass );\n        }\n      }\n      Constructor<?> constructor = jobDelegateClass.getConstructor( Spoon.class );\n      if ( constructor != null ) {\n        return (SpoonDelegate) constructor.newInstance( spoon );\n      } else {\n        throw new InstanceCreationException( \"Unable to get the constructor for \" + jobDelegateClass );\n      }\n    } catch ( Exception e ) {\n      throw new InstanceCreationException( \"Unable to instantiate object for \" + jobDelegateClass, e );\n    }\n  }\n\n  public SpoonDelegate constructSpoonTransDelegate( Spoon spoon ) throws InstanceCreationException {\n    try {\n      if ( transDelegateClass == null ) {\n        Constructor<?> constructor = DEFAULT_SPOONTRANSDELEGATE_CLASS.getConstructor( Spoon.class );\n        if ( constructor != null ) {\n          return (SpoonDelegate) constructor.newInstance( spoon );\n        } else {\n          throw new InstanceCreationException( \"Unable to get the constructor for \" + transDelegateClass );\n        }\n      }\n      Constructor<?> constructor = transDelegateClass.getConstructor( Spoon.class );\n      if ( constructor != null ) {\n        return (SpoonDelegate) constructor.newInstance( spoon );\n      } else {\n        throw new InstanceCreationException( \"Unable to get the constructor for \" + transDelegateClass );","sourceCodeStart":56,"sourceCodeEnd":92,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/ui/src/main/java/org/pentaho/di/ui/spoon/delegates/SpoonDelegateRegistry.java#L56-L92","documentation":"The catch block of constructSpoonJobDelegate converts every Exception — NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException — into InstanceCreationException 'Unable to instantiate object for <jobDelegateClass>' without chaining the cause. Hitting this message means reflective construction of the configured (or default) SpoonJobDelegate failed for any of those reasons and the underlying reason was discarded.","triggerScenarios":"jobDelegateClass is abstract or an interface (InstantiationException), its (Spoon) constructor is not public (IllegalAccessException), getConstructor finds no match (NoSuchMethodException), or the constructor throws during newInstance (InvocationTargetException).","commonSituations":"Custom delegate constructor dereferences spoon internals that are not yet initialized; class not visible to the classloader (plugin classloader mismatch); upgrade changed Spoon's constructor usage the delegate relied on.","solutions":["Pass the caught exception e (and e.getCause()) into the InstanceCreationException to expose the root cause","Make the delegate class public, concrete, with a public single-arg (Spoon) constructor","Check the delegate's constructor body for exceptions thrown during initialization","Test construction in isolation: new MyDelegate(spoon) directly to see the raw failure"],"exampleFix":"// before\ncatch ( Exception e ) {\n  throw new InstanceCreationException( \"Unable to instantiate object for \" + jobDelegateClass, e );\n}\n// after (already chains e, but ensure callers log getCause)\ncatch ( InvocationTargetException e ) {\n  throw new InstanceCreationException( \"Unable to instantiate object for \" + jobDelegateClass, e.getCause() );\n}","handlingStrategy":"try-catch","validationCode":"// verify delegate is constructible before relying on the registry\nObject test = jobDelegateClass.getConstructor(Spoon.class).newInstance(spoon); // in test/bootstrap code only","typeGuard":"boolean isConcreteWithSpoonCtor(Class<?> c) {\n  try {\n    return !c.isInterface() && !java.lang.reflect.Modifier.isAbstract(c.getModifiers())\n      && java.lang.reflect.Modifier.isPublic(c.getConstructor(Spoon.class).getModifiers());\n  } catch (NoSuchMethodException e) { return false; }\n}","tryCatchPattern":"try {\n  SpoonDelegate d = registry.constructSpoonJobDelegate(spoon);\n} catch (InstanceCreationException e) {\n  // cause is not chained in older code; re-verify manually\n  log.error(\"Job delegate instantiation failed for \" + jobDelegateClass, e);\n  SpoonDelegate d = new SpoonJobDelegate(spoon);\n}","preventionTips":["Instantiate the delegate directly in tests to surface the true root cause","Keep constructor bodies exception-free (lazy-init expensive deps)","Ensure the delegate class is visible to Spoon's classloader","Chain the caught exception when wrapping so causes aren't lost"],"tags":["reflection","instantiation","swallowed-exception"],"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"}