{"record":{"id":"9f6934040fcdc18e","repo":"apache/maven","slug":"substring-function-requires-2-or-3-arguments","errorCode":null,"errorMessage":"substring function requires 2 or 3 arguments","messagePattern":"substring function requires 2 or 3 arguments","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"impl/maven-impl/src/main/java/org/apache/maven/impl/model/profile/ConditionFunctions.java","lineNumber":105,"sourceCode":"     */\n    public Object lower(List<Object> args) {\n        if (args.size() != 1) {\n            throw new IllegalArgumentException(\"lower function requires exactly one argument\");\n        }\n        String s = ConditionParser.toString(args.get(0));\n        return s.toLowerCase();\n    }\n\n    /**\n     * Returns a substring of the given string.\n     *\n     * @param args A list containing 2 or 3 arguments: the string, start index, and optionally end index\n     * @return The substring\n     * @throws IllegalArgumentException if the number of arguments is not 2 or 3\n     */\n    public Object substring(List<Object> args) {\n        if (args.size() < 2 || args.size() > 3) {\n            throw new IllegalArgumentException(\"substring function requires 2 or 3 arguments\");\n        }\n        String s = ConditionParser.toString(args.get(0));\n        int start = toInt(args.get(1));\n        int end = args.size() == 3 ? toInt(args.get(2)) : s.length();\n        return s.substring(start, end);\n    }\n\n    /**\n     * Finds the index of a substring within a string.\n     *\n     * @param args A list containing two strings: the main string and the substring to find\n     * @return The index of the substring, or -1 if not found\n     * @throws IllegalArgumentException if the number of arguments is not exactly two\n     */\n    public Object indexOf(List<Object> args) {\n        if (args.size() != 2) {\n            throw new IllegalArgumentException(\"indexOf function requires exactly two arguments\");\n        }","sourceCodeStart":87,"sourceCodeEnd":123,"githubUrl":"https://github.com/apache/maven/blob/e4093d4e120eac99d6bdce5ba67cace2f3085c97/impl/maven-impl/src/main/java/org/apache/maven/impl/model/profile/ConditionFunctions.java#L87-L123","documentation":"substring() is a built-in function of Maven 4.1 profile activation conditions (<activation><condition>). ConditionFunctions.substring accepts exactly two or three arguments (string, start, optional end) and throws IllegalArgumentException for any other count; the activator records 'Error parsing profile activation condition' and leaves the profile inactive.","triggerScenarios":"A condition like substring(${java.version}) (one argument) or substring(${java.version}, 0, 2, 1) (four) — valid forms are substring(s, start) and substring(s, start, end).","commonSituations":"Expecting the string alone to be enough; carrying over an extra step/flags argument from another language's substring; forgetting the start index while extracting a prefix.","solutions":["Supply two or three arguments, e.g. substring(${java.version}, 0, 2) == '17'","Remember the end index is optional and defaults to the string length, but the start index is mandatory","Verify with mvn help:active-profiles after the fix"],"exampleFix":"<!-- before -->\n<condition>substring(${java.version}) == '17'</condition>\n\n<!-- after -->\n<condition>substring(${java.version}, 0, 2) == '17'</condition>","handlingStrategy":"validation","validationCode":"static boolean arityOk(String condition, String fn, int min, int max) {\n    int i = condition.indexOf(fn + \"(\");\n    if (i < 0) return true;\n    String args = condition.substring(i + fn.length() + 1, condition.indexOf(')', i));\n    int n = args.isBlank() ? 0 : args.split(\",\", -1).length;\n    return n >= min && n <= max;\n}\nboolean ok = arityOk(condition, \"substring\", 2, 3);","typeGuard":null,"tryCatchPattern":"try {\n    Object r = new ConditionParser(functions, resolver).parse(condition);\n} catch (IllegalArgumentException e) {\n    // wrong arity (also possible: StringIndexOutOfBounds values arrive as parse errors)\n}","preventionTips":["substring needs (string, start) or (string, start, end) — never just the string","Bounds are Java String.substring semantics: 0 <= start <= end <= length"],"tags":["maven","profile-activation","condition-functions","argument-mismatch","string"],"backgroundTag":"invalid-function-arguments","analyzedSha":"e4093d4e120eac99d6bdce5ba67cace2f3085c97","analyzedAt":"2026-08-21T22:58:24.034Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}