Conditionals Start New Lines

ID

javascript.conditionals_start_new_lines

Severity

high

Remediation Complexity

medium

Remediation Risk

low

Remediation Effort

medium

Resource

Code Smell

Language

JavaScript

Tags

code-style, control-flow, readability

Description

Reports an if statement that starts on the very line where the preceding if statement ended, so that a closing brace and the next condition share a line.

The test is purely positional: the if begins on the line where its immediately preceding sibling statement ended, and that sibling is itself an if. A genuine else if is out of reach — it is the body of the outer statement’s else, a descendant rather than a sibling — and so is a dangling if (a) if (b) …, where the inner conditional is the outer one’s body. An if preceded by any other kind of statement is not reported, because only a neighbouring conditional creates the else ambiguity.

Two conditionals packed onto one line (if (a) first(); if (b) second();) are reported by the same test: the second one still does not start its own line.

Rationale

// Bad
if (isExpired(token)) {
  refresh(token);
} if (isRevoked(token)) {
  reject(token);
}
  • The two conditionals look like one construct. A reader scanning the left margin sees a single decision and takes the second condition for an else if — the more so because a closing brace is exactly what an else if normally follows.

  • They are independent statements. Both conditions are evaluated, and both bodies run when both hold. If the author meant them as alternatives, the missing else is a live bug that the formatting conceals.

  • If the author meant them as independent checks, the formatting hides that the first branch falls through into the second — which is exactly the fact a reader needs in order to reason about the combination.

Either reading is a problem, and a line break costs nothing and settles the question. That is why this is reported as a defect and not as a formatting preference: the layout makes two different programs indistinguishable.

Remediation

Put the second conditional on its own line — and if the branches really are alternatives, say so with else.

// Good — independent checks, and it now looks like it
if (isExpired(token)) {
  refresh(token);
}
if (isRevoked(token)) {
  reject(token);
}

// Good — alternatives, and it now behaves like it
if (isExpired(token)) {
  refresh(token);
} else if (isRevoked(token)) {
  reject(token);
}

© 2026 Xygeni. All rights reserved