{"record":{"id":"2d4e4e59ccb97648","repo":"kestra-io/kestra","slug":"group-index-0-is-out-of-bounds-must-be-0","errorCode":null,"errorMessage":"Group index {0} is out of bounds: must be >= 0.","messagePattern":"Group index (.+?) is out of bounds: must be >= 0\\.","errorType":"validation","errorClass":"PebbleException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/io/kestra/core/runners/pebble/filters/RegexExtractFilter.java","lineNumber":71,"sourceCode":"            return null;\n        }\n\n        if (args.get(ARGUMENT_REGEX) == null) {\n            throw new PebbleException(\n                null,\n                MessageFormat.format(\"The argument ''{0}'' is required.\", ARGUMENT_REGEX),\n                lineNumber,\n                self.getName()\n            );\n        }\n\n        String regex = args.get(ARGUMENT_REGEX).toString();\n        int group = args.containsKey(ARGUMENT_GROUP) && args.get(ARGUMENT_GROUP) != null\n            ? ((Number) args.get(ARGUMENT_GROUP)).intValue()\n            : 0;\n\n        if (group < 0) {\n            throw new PebbleException(\n                null,\n                MessageFormat.format(\"Group index {0} is out of bounds: must be >= 0.\", group),\n                lineNumber,\n                self.getName()\n            );\n        }\n\n        Matcher matcher;\n        try {\n            matcher = RegexUtils.matcher(Pattern.compile(regex), input.toString());\n        } catch (PatternSyntaxException e) {\n            throw new PebbleException(e, MessageFormat.format(\"Invalid regex ''{0}'': {1}\", regex, e.getDescription()), lineNumber, self.getName());\n        }\n        try {\n            if (matcher.find()) {\n                if (group > matcher.groupCount()) {\n                    throw new PebbleException(\n                        null,","sourceCodeStart":53,"sourceCodeEnd":89,"githubUrl":"https://github.com/kestra-io/kestra/blob/823fada9274c4f9c251ea0a516460a4f7d958032/core/src/main/java/io/kestra/core/runners/pebble/filters/RegexExtractFilter.java#L53-L89","documentation":"Thrown by the 'regexExtract' Pebble filter when the `group` argument is a negative integer. Group 0 means the whole match and groups 1..n refer to capture groups, so negative values are meaningless and rejected before the pattern is compiled.","triggerScenarios":"Passing `group=-1` or any negative number explicitly, or passing a computed group value from a variable/inputs that evaluated to a negative number (e.g. `group=index - 1` with `index=0`).","commonSituations":"Off-by-one arithmetic when computing the group index dynamically; treating the group as zero-based for capture groups when it is actually 1-based (group 0 is the full match).","solutions":["Use group 0 for the whole match or a positive capture-group index.","Guard dynamic indices: `group=max(0, myIndex)`.","Re-read the filter Javadoc: group 0 = full match, 1..n = capture groups."],"exampleFix":"# before\n{{ s | regexExtract(regex=\"(a)(b)\", group=idx - 1) }}\n# after\n{{ s | regexExtract(regex=\"(a)(b)\", group=(idx > 0 ? idx : 0)) }}","handlingStrategy":"validation","validationCode":"# Clamp the group index to a valid range before calling:\n{{ s | regexExtract(regex=\"(a)(b)\", group=(idx >= 0 ? idx : 0)) }}","typeGuard":"# Pebble: `is number` plus a >= 0 check guards the group argument:\n{% set g = (groupInput is number and groupInput >= 0) ? groupInput : 0 %}","tryCatchPattern":null,"preventionTips":["Treat group 0 as the full match and 1..n as capture groups.","Compute group indices defensively with a max(0, x) clamp.","Unit-test arithmetic that derives the group index."],"tags":["pebble-filter","regex-extract","argument-validation","regex","group-index"],"backgroundTag":null,"analyzedSha":"823fada9274c4f9c251ea0a516460a4f7d958032","analyzedAt":"2026-08-14T06:15:17.947Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}