pentaho/pentaho-kettle · error · KettleValueException
ScriptValuesMod.Log.CouldNotAttachAdditionalScripts
Error message
ScriptValuesMod.Log.CouldNotAttachAdditionalScripts
What it means
addValues() attaches additional Java objects to the JavaScript scope via Context.javaToJS and ScriptableObject.putProperty for each entry in meta.getAddClasses(); any Exception during this wrapping is rethrown as a KettleValueException with message ScriptValuesMod.Log.CouldNotAttachAdditionalScripts. It means one of the configured Java objects/classes could not be exposed to the script engine.
Solutions
- Check the log for the full stack trace — the cause 'e' identifies which addClass entry failed.
- Verify the jar containing the added Java class is on the Pentaho classpath (lib/ or the step's plugin lib) on the machine running the transformation.
- Give every added class a non-empty, valid JavaScript identifier as its JS name.
- Remove or disable stale addClass entries pointing at classes that no longer exist.
- Test the wrapping logic outside Kettle if using a custom object to confirm Rhino can wrap its type.
Example fix
// before (step metadata) <jsName></jsName> <!-- blank JS name -> putProperty fails --> // after <jsName>myHelper</jsName> <!-- valid non-empty identifier -->
Defensive patterns
Strategy: try-catch
Validate before calling
// Java, verify each added class is loadable before running the transformation
for (ScriptValuesModAddClasses ac : meta.getAddClasses()) {
if (ac.getAddObject() == null) throw new IllegalStateException("Added object is null");
if (ac.getJSName() == null || !ac.getJSName().matches("[A-Za-z_$][A-Za-z0-9_$]*"))
throw new IllegalStateException("Invalid JS name: '" + ac.getJSName() + "'");
Class.forName(ac.getAddObject().getClass().getName()); // triggers classpath check
} Try / catch
try {
transformation.execute(params);
} catch (KettleValueException e) {
if (e.getMessage().contains("CouldNotAttachAdditionalScripts")) {
log.error("Failed to attach addClasses: " + e.getCause(), e.getCause()); // cause names the failing entry
} else { throw e; }
} Prevention
- Keep custom jars in the correct lib/plugin directory on every server that runs the transformation.
- Always assign a valid JavaScript identifier as the JS name for added classes.
- Remove entries for classes removed in refactors; validate addClasses at transformation design time.
- Inspect e.getCause() — it pinpoints which addClass entry and which failure (class vs name).
When it happens
Trigger: Context.javaToJS(meta.getAddClasses()[i].getAddObject(), data.scope) throws — the addObject is null/incompatible or the Rhino context cannot wrap it — or ScriptableObject.putProperty fails because getJSName() is empty or not a valid identifier, inside the try block in addValues().
Common situations: A 'Java classes/scripts' entry references an object whose class is missing at runtime (plugin/jar not on classpath, class-not-found deferred into javaToJS); JS name left blank or containing invalid characters; the added object's type is not wrap-able by the bundled Rhino version; transformation moved to a server missing the custom jar.
Related errors
- ScriptValuesMod.Log.CouldNotAddDefaultFunctions
- iae.getMessage()
- A deadlock was detected between steps
- AbsSecurityManager.ERROR_0003_UNABLE_TO_ACCESS_ROLE_BINDING_WEBSVC
- AbsSecurityManager.ERROR_0004_UNABLE_TO_APPLY_LOGICAL_ROLES_TO_RUNTIME_ROLE
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/074e76ef147b6827.
Report an issue: GitHub.
Appendix: source
Thrown at engine/src/main/java/org/pentaho/di/trans/steps/scriptvalues_mod/ScriptValuesMod.java:262
}
}
// also add the meta information for the whole row
//
Scriptable jsrowMeta = Context.toObject( rowMeta, data.scope );
data.scope.put( "rowMeta", data.scope, jsrowMeta );
// Modification for Additional Script parsing
//
try {
if ( meta.getAddClasses() != null ) {
for ( int i = 0; i < meta.getAddClasses().length; i++ ) {
Object jsOut = Context.javaToJS( meta.getAddClasses()[ i ].getAddObject(), data.scope );
ScriptableObject.putProperty( data.scope, meta.getAddClasses()[ i ].getJSName(), jsOut );
}
}
} catch ( Exception e ) {
throw new KettleValueException( BaseMessages.getString(
PKG, "ScriptValuesMod.Log.CouldNotAttachAdditionalScripts" ), e );
}
// Adding some default JavaScriptFunctions to the System
try {
Context.javaToJS( ScriptValuesAddedFunctions.class, data.scope );
( (ScriptableObject) data.scope ).defineFunctionProperties(
ScriptValuesAddedFunctions.jsFunctionList, ScriptValuesAddedFunctions.class,
ScriptableObject.DONTENUM );
} catch ( Exception ex ) {
// System.out.println(ex.toString());
throw new KettleValueException( BaseMessages.getString(
PKG, "ScriptValuesMod.Log.CouldNotAddDefaultFunctions" ), ex );
}
// Adding some Constants to the JavaScript
try {
View on GitHub (pinned to f3058517a1)