# Catastrophic backtracking, minimal example

`/^(a+)+$/`

**Match a whole string consisting of one or more of (one or more of "a").**

> **Do not run this against untrusted input.** See the warnings below.

## Step by step

- `^` — Anchor to the start of the input.
- `(a+)+` — Match one or more of (one or more of "a").
- `$` — Anchor to the end of the input.

## Warnings

### Catastrophic backtracking — this pattern can hang (error)

A quantifier repeats a group that itself contains an unbounded quantifier over an overlapping character set. On input that ALMOST matches, the engine has exponentially many ways to split the text between the two quantifiers and must try all of them before it can report failure. A few dozen characters can take minutes of CPU, which makes this a denial-of-service vector if the pattern ever runs against untrusted input.

**Fix:** Remove one level of repetition. Usually the inner quantifier alone is enough: (a+)+ means the same thing as a+. Where the nesting is genuinely needed, make the inner part non-overlapping or use an atomic group in an engine that has one — JavaScript does not.

### Anchors match string ends, not line ends (info)

Without the m flag, ^ and $ match only the very start and end of the input — not the start and end of each line. On multi-line input this is often not what was intended.

**Fix:** Add the m flag if the pattern should apply per line.

## Details

- Capture groups: 1

---

Canonical URL: https://regex-explainer.gumballtools.com/regex/catastrophic-backtracking-example
JSON API: `GET https://regex-explainer.gumballtools.com/api/v1/explain?pattern=...`
MCP endpoint: `https://regex-explainer.gumballtools.com/api/mcp`
