kestra-io/kestra · error · PebbleException

Group index {0} is out of bounds: the pattern has only {1} c

Error message

Group index {0} is out of bounds: the pattern has only {1} capture group(s).

What it means

Thrown by the 'regexExtract' Pebble filter when the requested capture group index exceeds the number of capture groups in the compiled pattern. Group 0 (the whole match) is always available; this check fires only when `group` is greater than `matcher.groupCount()`, after a match has already been found.

Source

Thrown at core/src/main/java/io/kestra/core/runners/pebble/filters/RegexExtractFilter.java:88

        if (group < 0) {
            throw new PebbleException(
                null,
                MessageFormat.format("Group index {0} is out of bounds: must be >= 0.", group),
                lineNumber,
                self.getName()
            );
        }

        Matcher matcher;
        try {
            matcher = RegexUtils.matcher(Pattern.compile(regex), input.toString());
        } catch (PatternSyntaxException e) {
            throw new PebbleException(e, MessageFormat.format("Invalid regex ''{0}'': {1}", regex, e.getDescription()), lineNumber, self.getName());
        }
        try {
            if (matcher.find()) {
                if (group > matcher.groupCount()) {
                    throw new PebbleException(
                        null,
                        MessageFormat.format("Group index {0} is out of bounds: the pattern has only {1} capture group(s).", group, matcher.groupCount()),
                        lineNumber,
                        self.getName()
                    );
                }
                return matcher.group(group);
            }
        } catch (RegexUtils.RegexTimeoutException e) {
            throw new PebbleException(e, e.getMessage(), lineNumber, self.getName());
        }
        return null;
    }
}

View on GitHub (pinned to 823fada927)

Solutions

  1. Count the capture groups (each `(...)` is one) and use an index within range.
  2. Use group 0 if you only need the full match.
  3. Use named groups and reference them by name where supported.

Example fix

# before - only 1 capture group
{{ "a-b" | regexExtract(regex="(\\w+)", group=2) }}
# after
{{ "a-b" | regexExtract(regex="(\\w+)", group=1) }}
Defensive patterns

Strategy: validation

Validate before calling

# Count capture groups in the pattern and clamp the index:
# int max = matcher.groupCount();
# int safeGroup = Math.min(Math.max(0, requested), max);
{{ s | regexExtract(regex="(a)(b)", group=1) }}

Prevention

When it happens

Trigger: Asking for group 2 on a pattern with only one capture group; requesting a group on a pattern that has no capture groups at all (groupCount() == 0).

Common situations: Adding/removing parentheses in the regex without updating the group index; assuming the index is zero-based for capture groups (it is 1-based; 0 is the full match).

Related errors


AI-assisted analysis of kestra-io/kestra@823fada927 (2026-08-14). Data as JSON: /api/errors/a8bf615ae1974c5d. Report an issue: GitHub.