# no-unreachable-loop

> Disallow loops with a body that can only run once

If every path through a loop's body ends in `break`, `return`, or `throw`, the loop never gets to a second pass. Usually a condition is missing around the exit, or you meant `continue`.

{/* Generated by src/codegen/lint-rule-docs.ts. Do not edit this section. */}

## Configure

Off by default. To turn it on:

```toml bunfig.toml
[lint.rules]
"no-unreachable-loop" = "error" # or "warn"
```

Every option, set to its default:

```toml bunfig.toml
[lint.rules]
"no-unreachable-loop" = ["error", {
  ignore = [], # list of strings
}]
```

{/* End of the generated section. */}

## Examples

Reported. The loop only ever looks at the first result:

{/* bad */}
```js
function firstError(results) {
  for (const result of results) {
    if (result.ok) {
      return null;
    } else {
      return result.error;
    }
  }
}
```

Not reported:

{/* good */}
```js
function firstError(results) {
  for (const result of results) {
    if (!result.ok) {
      return result.error;
    }
  }
  return null;
}
```

## Options

| Option | Default | What it does |
| --- | --- | --- |
| `ignore` | `[]` | Kinds of loops to skip: `"WhileStatement"`, `"DoWhileStatement"`, `"ForStatement"`, `"ForInStatement"`, `"ForOfStatement"`. |

A `for...of` loop that returns right away is a short way to get an iterable's first item. By default it's reported:

{/* bad */}
```js
function first(items) {
  for (const item of items) {
    return item;
  }
}
```

{/* good {"options": [{"ignore": ["ForOfStatement"]}]} */}
```js
function first(items) {
  for (const item of items) {
    return item;
  }
}
```
