pentaho/pentaho-kettle · error · KettleException
No setter defined for
Error message
No setter defined for <rootClass>
What it means
While walking an injection property path, the engine needed to instantiate an intermediate (non-leaf) object whose current value is null; if that path level has only a getter and no setter, the object cannot be assigned, so KettleException('No setter defined for <class>') is thrown.
Solutions
- Initialize the nested object before injection (call the step's init/defaults so the getter is non-null)
- Add a setter to the intermediate class so the injector can install a new instance
- Ensure the plugin class implements the expected bean-injection conventions (getters plus setters for nested injectable beans)
Example fix
// before
public Options getOptions() { return options; } // options==null, no setter
// after
public Options getOptions() { return options = options != null ? options : new Options(); }
public void setOptions(Options o) { this.options = o; } Defensive patterns
Strategy: try-catch
Validate before calling
// ensure intermediate objects exist before injection if (meta.getNestedOptions() == null) meta.setNestedOptions(new NestedOptions());
Try / catch
try { injector.setProperty(root, propName, data, n); }
catch (KettleException e) { throw new IllegalStateException("Path object not settable for " + propName + ": " + e.getMessage(), e); } Prevention
- Give every injectable nested bean both a getter and a setter
- Call the metadata class's defaults/setDefault() before injection
- Review plugin classes for lazy-null fields reachable by injection paths
When it happens
Trigger: A property path passes through a nested bean whose getter returns null and which lacks a setter (e.g. getOptions() returns null with no setOptions), forcing the injector to create-and-assign a new instance — impossible without a setter.
Common situations: Plugin classes exposing read-only nested objects; step class refactored to drop setters; injection into fields that are only initialized lazily by the plugin's own init().
Understand the failure class
Background: "not installed", "pip install", "required for": how missing-dependency errors surface across open-source libraries — this error's family across 34 libraries.
Related errors
- Error inject property
- Property not found
- Property ' ' has more than one array in path for injection…
- Property ' ' not found for injection to
- Unexpected error occurred while injecting metadata
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/7a416b31e4d801d1.
Report an issue: GitHub.
Appendix: source
Thrown at engine/src/main/java/org/pentaho/di/core/injection/bean/BeanInjector.java:260
next = createObject( s.leafClass, root );
existList.set( index, next );
}
obj = next;
break;
case NONE:
// plain field
if ( s.field != null ) {
next = s.field.get( obj );
if ( next == null ) {
next = createObject( s.leafClass, root );
s.field.set( obj, next );
}
obj = next;
} else if ( s.getter != null ) {
next = s.getter.invoke( obj );
if ( next == null ) {
if ( s.setter == null ) {
throw new KettleException( "No setter defined for " + root.getClass() );
}
next = s.leafClass.newInstance();
s.setter.invoke( obj, next );
}
obj = next;
} else {
throw new KettleException( "No field or getter defined for " + root.getClass() );
}
break;
}
} else {
// set to latest field
if ( !s.convertEmpty ) {
if ( data != null ) {
if ( data.isEmptyValue( dataName ) ) {
return true;
}
} else {View on GitHub (pinned to f3058517a1)