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

  1. Check the log for the full stack trace — the cause 'e' identifies which addClass entry failed.
  2. 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.
  3. Give every added class a non-empty, valid JavaScript identifier as its JS name.
  4. Remove or disable stale addClass entries pointing at classes that no longer exist.
  5. 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

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


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)