no-unmodified-loop-condition

Disallow loop conditions that test variables the loop never changes

If nothing in a while, do...while, or for loop changes the variables in its condition, the loop either never runs or never stops. Usually someone forgot the update, or it changes the wrong variable.

Configure#

Off by default. To turn it on:

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

Every option, set to its default:

bunfig.toml
[lint.rules]
"no-unmodified-loop-condition" = ["error", {
  checkConditionalExpressions = false,
}]

Examples#

example.js1 problem
let node = list.head;

while (node) {
  print(node.value);
  list.next();
}
example.jsNo problems
let node = list.head;

while (node) {
  print(node.value);
  node = node.next;
}

In a comparison, the loop only needs to change one side:

example.jsNo problems
const limit = 3;
let attempts = 0;

while (attempts < limit) {
  attempts++;
}

A property or a call's result can change without an assignment, so they aren't checked. Neither is a comparison that contains one:

example.jsNo problems
let max = 10;

while (queue.length > max) {
  handle(queue);
}

A variable also counts as changed if the loop uses a function declaration that assigns to it:

example.jsNo problems
let done = false;

function finish() {
  done = true;
}

while (!done) {
  finish();
}

Options#

OptionDefaultWhat it does
checkConditionalExpressionsfalseCheck each variable of a ? : in the condition separately.

By default a ? : is treated like a comparison, so one changed variable is enough.

example.jsNo problems
let urgent = true;
let high = 3;
let low = 5;

while (urgent ? high : low) {
  urgent = isUrgent();
}

With the option, high and low are reported:

example.jswith { "checkConditionalExpressions": true }2 problems
let urgent = true;
let high = 3;
let low = 5;

while (urgent ? high : low) {
  urgent = isUrgent();
}