pentaho/pentaho-kettle · error · RhinoRuntimeError
The function call decode is not valid :
Error message
The function call decode is not valid :
What it means
The `decode()` ScriptValuesMod function wraps its whole comparison logic in a try/catch and re-throws any exception (regex-free string comparison failures, invalid types, Context conversion errors) as this runtime error with the original message appended. The message shown was empty, meaning the underlying exception had a null/blank getMessage().
Solutions
- Guard input values with a null check before calling decode (e.g. `value == null ? def : decode(value, ...)`)
- Convert fields to strings explicitly before passing them: decode(str(value), ...)
- Rebuild the message by enabling the underlying exception: log ArgList types before calling decode to find the offending value
Example fix
// before var out = decode(fieldA, 'x', 1, 0); // after var out = (fieldA == null) ? 0 : decode(Context.toString(fieldA), 'x', 1, 0);
Defensive patterns
Strategy: type-guard
Validate before calling
if (value == null) { logError('decode input is null'); } else { var out = decode(String(value), 'x', 1, 0); } Type guard
function isSafeForDecode(v) { return v !== null && v !== undefined; } Try / catch
try {
var out = decode(v, 'x', 1, 0);
} catch (e) {
if (String(e).indexOf('decode is not valid') !== -1) { out = 0; } else { throw e; }
} Prevention
- Null-guard every field read from the row before decode
- Coerce numeric fields to strings before comparison
- Test the JavaScript step with sample rows including nulls
When it happens
Trigger: Any runtime exception inside decode's comparison loop: null values being compared via equals without guarding, incompatible object types passed as ArgList, or Context.toString conversion failures where e.getMessage() returns null.
Common situations: Passing null fields from a previous step into decode(); passing non-string/non-comparable objects (e.g. binary, Number vs String) as search values; Kettle field values that are null on the first row.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Function call replace is not valid :
- The function call decode requires more than 1 argument.
- The function call replace is not valid (wrong number of…
- The function call str2num requires 1, 2, or 3 arguments.
- 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/2ea52df1f4033fc8.
Report an issue: GitHub.
Appendix: source
Thrown at engine/src/main/java/org/pentaho/di/trans/steps/scriptvalues_mod/ScriptValuesAddedFunctions.java:1537
} else if ( isUndefined( ArgList, new int[] { 0, 1 } ) ) {
return Context.getUndefinedValue();
}
Object objToCompare = ArgList[0];
for ( int i = 1; i < ArgList.length - 1; i = i + 2 ) {
if ( ArgList[i].equals( objToCompare ) ) {
return ArgList[i + 1];
}
}
if ( ArgList.length % 2 == 0 ) {
return ArgList[ArgList.length - 1];
} else {
return objToCompare;
}
} else {
throw Context.reportRuntimeError( "The function call decode requires more than 1 argument." );
}
} catch ( Exception e ) {
throw Context.reportRuntimeError( "The function call decode is not valid : " + e.getMessage() );
}
}
public static String replace( Context actualContext, Scriptable actualObject, Object[] ArgList,
Function FunctionContext ) {
try {
if ( ArgList.length >= 2 && ( ArgList.length - 1 ) % 2 == 0 ) {
if ( isNull( ArgList, new int[] { 0, 1 } ) ) {
return null;
} else if ( isUndefined( ArgList, new int[] { 0, 1 } ) ) {
return (String) Context.getUndefinedValue();
}
String objForReplace = Context.toString( ArgList[0] );
for ( int i = 1; i < ArgList.length - 1; i = i + 2 ) {
objForReplace =
objForReplace.replaceAll( Context.toString( ArgList[i] ), Context.toString( ArgList[i + 1] ) );
}
return objForReplace;View on GitHub (pinned to f3058517a1)