{"record":{"id":"b9cb37609296660a","repo":"pentaho/pentaho-kettle","slug":"the-function-call-substr-requires-2-or-3-arguments","errorCode":null,"errorMessage":"The function call substr requires 2 or 3 arguments.","messagePattern":"The function call substr requires 2 or 3 arguments\\.","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"engine/src/main/java/org/pentaho/di/trans/steps/script/ScriptAddedFunctions.java","lineNumber":1645,"sourceCode":"\n        if ( from < 0 ) {\n          throw new RuntimeException( \"start smaller than 0\" );\n        }\n        if ( len < 0 ) {\n          len = 0; // Make it compatible with Javascript substr\n        }\n\n        to = from + len;\n        strLen = sRC.length();\n        if ( to > strLen ) {\n          to = strLen;\n        }\n        sRC = sRC.substring( from, to );\n      } catch ( Exception e ) {\n        throw new RuntimeException( \"The function call substr is not valid : \" + e.getMessage() );\n      }\n    } else {\n      throw new RuntimeException( \"The function call substr requires 2 or 3 arguments.\" );\n    }\n    return sRC;\n  }\n\n  // Resolve an IP address\n  public static String resolveIP( ScriptEngine actualContext, Bindings actualObject, Object[] ArgList,\n    Object FunctionContext ) {\n    String sRC = \"\";\n    if ( ArgList.length == 2 ) {\n      try {\n        InetAddress addr = InetAddress.getByName( (String) ArgList[0] );\n        if ( ( (String) ArgList[1] ).equals( \"IP\" ) ) {\n          sRC = addr.getHostName();\n        } else {\n          sRC = addr.getHostAddress();\n        }\n        if ( sRC.equals( ArgList[0] ) ) {\n          sRC = \"-\";","sourceCodeStart":1627,"sourceCodeEnd":1663,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/engine/src/main/java/org/pentaho/di/trans/steps/script/ScriptAddedFunctions.java#L1627-L1663","documentation":"Arity guard for substr: the function was called with an argument count other than 2 or 3 (string + start, or string + start + length). The implementation only handles those two signatures; anything else reaches the final else-branch and throws.","triggerScenarios":"Calling substr(str) with one argument, substr() with none, or substr(str, start, len, extra) with more than three arguments.","commonSituations":"Porting code that used substring(begin,end) and adding a stray argument; forgetting the start index; copy-paste leaving a trailing comma creating an extra argument.","solutions":["Call with substr(str, start) or substr(str, start, len).","Remember indices/lengths are numbers: substr(field, 0, 5).","Remove accidental extra arguments from the call."],"exampleFix":"// before\nvar s = substr(str);\n// after\nvar s = substr(str, 0, 5);","handlingStrategy":"validation","validationCode":"if (arguments.length === 2 || arguments.length === 3) { s = substr.apply(null, arguments); } else { s = ''; }","typeGuard":"function hasValidSubstrArity(args){ return args.length === 2 || args.length === 3; }","tryCatchPattern":"try { s = substr(str, start, len); } catch (e) { if (/requires 2 or 3 arguments/.test(e.message)) s = ''; else throw e; }","preventionTips":["Always supply the start index.","Cap at three arguments.","Check the signature in the step's function documentation."],"tags":["javascript","substr","argument-count","script-step"],"backgroundTag":"missing-required-argument","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"}