pentaho/pentaho-kettle · error · RuntimeException

The function call rtrim is not valid :

Error message

The function call rtrim is not valid : 

What it means

rtrim() is one of the JavaScript helper functions Kettle injects into the Script step. It strips trailing whitespace with strValueToTrim.replaceAll("\\s+$", ""). Any exception inside the function (bad argument count, non-String first argument, null input) is caught and rethrown as this generic RuntimeException, so the original cause is only visible in e.getMessage().

Solutions

  1. Pass exactly one argument and ensure it is a string (wrap with str() or concatenation with "" if needed).
  2. Check e.getMessage() in the stack trace to see the underlying cause (argument count vs ClassCastException).
  3. Handle null inputs before calling rtrim, e.g. if (v != null) v = rtrim(v).
  4. If non-string trimming semantics are needed, implement it directly in the script instead of relying on rtrim.

Example fix

// before
var trimmed = rtrim(myNumericField);
// after
var trimmed = rtrim(str(myNumericField));
Defensive patterns

Strategy: type-guard

Validate before calling

var trimmed = (value != null) ? rtrim(String(value)) : null;

Type guard

function isTrimSafe(v) { return v != null && (v instanceof java.lang.String || typeof v === "string"); }

Try / catch

try {
  var trimmed = rtrim(value);
} catch (e) {
  // message is 'The function call rtrim is not valid : ' + cause
  Logger.LogBasic("rtrim failed: " + e.message);
  trimmed = value;
}

Prevention

When it happens

Trigger: Calling rtrim() in a Script step with zero arguments, more than one argument, or with an argument that is not a String and cannot be cast (ClassCastException) or otherwise fails during the regex replaceAll.

Common situations: Passing a numeric or Date field instead of a string field; passing null from an upstream step; accidentally passing two arguments expecting (value, chars) semantics like some SQL dialects.

Understand the failure class

Background: "must be a positive integer", "cannot be empty", "invalid argument": how invalid-argument errors work across open-source libraries — this error's family across 33 libraries.

Related errors


AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13). Data as JSON: /api/errors/78f65346c16d42b0. Report an issue: GitHub.

Appendix: source

Thrown at engine/src/main/java/org/pentaho/di/trans/steps/script/ScriptAddedFunctions.java:773

    }
  }

  public static String rtrim( ScriptEngine actualContext, Bindings actualObject, Object[] ArgList,
    Object FunctionContext ) {
    try {
      if ( ArgList.length == 1 ) {
        if ( isNull( ArgList[0] ) ) {
          return null;
        } else if ( isUndefined( ArgList[0] ) ) {
          return (String) undefinedValue;
        }
        String strValueToTrim = (String) ArgList[0];
        return strValueToTrim.replaceAll( "\\s+$", "" );
      } else {
        throw new RuntimeException( "The function call rtrim requires 1 argument." );
      }
    } catch ( Exception e ) {
      throw new RuntimeException( "The function call rtrim is not valid : " + e.getMessage() );
    }
  }

  public static String lpad( ScriptEngine actualContext, Bindings actualObject, Object[] ArgList,
    Object FunctionContext ) {

    // (String valueToPad, String filler, int size) {
    try {
      if ( ArgList.length == 3 ) {
        if ( isNull( ArgList, new int[] { 0, 1, 2 } ) ) {
          return null;
        } else if ( isUndefined( ArgList, new int[] { 0, 1, 2 } ) ) {
          return (String) undefinedValue;
        }
        String valueToPad = (String) ArgList[0];
        String filler = (String) ArgList[1];
        int size = (Integer) ArgList[2];

View on GitHub (pinned to f3058517a1)