{"record":{"id":"074e76ef147b6827","repo":"pentaho/pentaho-kettle","slug":"scriptvaluesmod-log-couldnotattachadditionalscripts","errorCode":null,"errorMessage":"ScriptValuesMod.Log.CouldNotAttachAdditionalScripts","messagePattern":"ScriptValuesMod\\.Log\\.CouldNotAttachAdditionalScripts","errorType":"exception","errorClass":"KettleValueException","httpStatus":null,"severity":"error","filePath":"engine/src/main/java/org/pentaho/di/trans/steps/scriptvalues_mod/ScriptValuesMod.java","lineNumber":262,"sourceCode":"          }\n        }\n\n        // also add the meta information for the whole row\n        //\n        Scriptable jsrowMeta = Context.toObject( rowMeta, data.scope );\n        data.scope.put( \"rowMeta\", data.scope, jsrowMeta );\n\n        // Modification for Additional Script parsing\n        //\n        try {\n          if ( meta.getAddClasses() != null ) {\n            for ( int i = 0; i < meta.getAddClasses().length; i++ ) {\n              Object jsOut = Context.javaToJS( meta.getAddClasses()[ i ].getAddObject(), data.scope );\n              ScriptableObject.putProperty( data.scope, meta.getAddClasses()[ i ].getJSName(), jsOut );\n            }\n          }\n        } catch ( Exception e ) {\n          throw new KettleValueException( BaseMessages.getString(\n            PKG, \"ScriptValuesMod.Log.CouldNotAttachAdditionalScripts\" ), e );\n        }\n\n        // Adding some default JavaScriptFunctions to the System\n        try {\n          Context.javaToJS( ScriptValuesAddedFunctions.class, data.scope );\n          ( (ScriptableObject) data.scope ).defineFunctionProperties(\n            ScriptValuesAddedFunctions.jsFunctionList, ScriptValuesAddedFunctions.class,\n            ScriptableObject.DONTENUM );\n        } catch ( Exception ex ) {\n          // System.out.println(ex.toString());\n          throw new KettleValueException( BaseMessages.getString(\n            PKG, \"ScriptValuesMod.Log.CouldNotAddDefaultFunctions\" ), ex );\n        }\n\n        // Adding some Constants to the JavaScript\n        try {\n","sourceCodeStart":244,"sourceCodeEnd":280,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/engine/src/main/java/org/pentaho/di/trans/steps/scriptvalues_mod/ScriptValuesMod.java#L244-L280","documentation":"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.","triggerScenarios":"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().","commonSituations":"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.","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."],"exampleFix":"// before (step metadata)\n<jsName></jsName>  <!-- blank JS name -> putProperty fails -->\n// after\n<jsName>myHelper</jsName>  <!-- valid non-empty identifier -->","handlingStrategy":"try-catch","validationCode":"// Java, verify each added class is loadable before running the transformation\nfor (ScriptValuesModAddClasses ac : meta.getAddClasses()) {\n  if (ac.getAddObject() == null) throw new IllegalStateException(\"Added object is null\");\n  if (ac.getJSName() == null || !ac.getJSName().matches(\"[A-Za-z_$][A-Za-z0-9_$]*\"))\n    throw new IllegalStateException(\"Invalid JS name: '\" + ac.getJSName() + \"'\");\n  Class.forName(ac.getAddObject().getClass().getName()); // triggers classpath check\n}","typeGuard":null,"tryCatchPattern":"try {\n  transformation.execute(params);\n} catch (KettleValueException e) {\n  if (e.getMessage().contains(\"CouldNotAttachAdditionalScripts\")) {\n    log.error(\"Failed to attach addClasses: \" + e.getCause(), e.getCause()); // cause names the failing entry\n  } else { throw e; }\n}","preventionTips":["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)."],"tags":["kettle","pentaho","rhino","classpath","script-engine"],"backgroundTag":"module-init-failed","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"}