no-fallthrough

Disallow case clauses that run on into the next one

error by default

A case that doesn't end with break, return, throw, continue or process.exit() keeps going into the code of the next case. A forgotten break runs code for a value it wasn't written for, and nothing fails at that line.

If you want the fallthrough, say so in a comment right before the next case. // falls through, // fall-through, // fallthrough and // no break all work, in any case. Several case labels in a row that share one body are allowed.

This rule is on by default.

Configure#

On by default as an error. To turn it off:

bunfig.toml
[lint.rules]
"no-fallthrough" = "off" # or "warn"

Every option, set to its default:

bunfig.toml
[lint.rules]
"no-fallthrough" = ["error", {
  commentPattern = "(?i:falls?[\\s-]?through|no\\s?break)",
  allowEmptyCase = false,
  reportUnusedFallthroughComment = false,
}]

Examples#

example.js1 problem
switch (post.status) {
  case "draft":
    publish(post);
  case "published":
    notify(post);
    break;
}
example.jsNo problems
switch (post.status) {
  case "draft":
    publish(post);
    break;
  case "published":
    notify(post);
    break;
}

process.exit() and process.abort() end a case too. With --type-aware, so does any call that returns never. With an ESLint config file they don't, as in ESLint.

example.jsNo problems
switch (command) {
  case "help":
    printUsage();
    process.exit(0);
  case "version":
    console.log(version);
    break;
}
example.jsNo problems
switch (post.status) {
  case "draft":
    publish(post);
  // falls through
  case "published":
  case "pinned":
    notify(post);
    break;
}
example.jsNo problems
switch (post.status) {
  case "draft":
    publish(post);
  /* intentional fall-through */
  case "published":
    notify(post);
  // no break
  default:
    log(post);
}

Options#

OptionDefaultWhat it does
commentPatternsee belowA regular expression for the comment that allows a fallthrough. It replaces the default.
allowEmptyCasefalseAllow an empty case with a blank line before the next one.
reportUnusedFallthroughCommentfalseReport a fallthrough comment after a case that can't fall through.

The default commentPattern is (?i:falls?[\s-]?through|no\s?break). With an ESLint config file it's ESLint's own, falls?\s?through in any case, which doesn't accept fall-through or no break.

example.jswith { "commentPattern": "break omitted" }No problems
switch (post.status) {
  case "draft":
    publish(post);
  // break omitted on purpose
  case "published":
    notify(post);
}

An empty case followed by a blank line looks like its body was deleted, so it's reported unless you set allowEmptyCase:

example.js1 problem
switch (post.status) {
  case "draft":

  case "published":
    notify(post);
}
example.jswith { "allowEmptyCase": true }No problems
switch (post.status) {
  case "draft":

  case "published":
    notify(post);
}

With reportUnusedFallthroughComment, a comment that's no longer true is reported:

example.jswith { "reportUnusedFallthroughComment": true }1 problem
switch (post.status) {
  case "draft":
    publish(post);
    break;
  // falls through
  case "published":
    notify(post);
}