quick-lint-js

quick-lint-js finds bugs in JavaScript programs.

quick-lint-js can find the following warnings and errors in your code:

E001: variable assigned before its declaration

Variables declared with let can only be reassigned by code below the declaration. The assignment will crash with a ReferenceError if you assign to the variable.

function getNumberOfChocolates() { return 3; }
let shouldEatChocolates = true;

if (shouldEatChocolates) {
  chocolates = 0;
}
let chocolates = getNumberOfChocolates();

To fix this error, move the declaration above the assignment:

function getNumberOfChocolates() { return 3; }
let shouldEatChocolates = true;

let chocolates = getNumberOfChocolates();
if (shouldEatChocolates) {
  chocolates = 0;
}

E002: assignment to const global variable

Infinity, NaN, and undefined are global variables which cannot be changed. Assignments to these variables are silently ignored.

NaN = 0;
undefined = null;

To fix this error, pick a different variable to assign to.

E003: assignment to const variable

You cannot reassign variables declared with const. The assignment will crash with a ReferenceError if you run the code.

const pi = 3.14;
pi = 6;

const friends = ["Alice"];
friends = ["Bob"];

To fix this error, assign to a different variable, declare a new variable with a different name, or change const to let:

let pi = 3.14;
pi = 6;

const friends = ["Alice"];
const acquaintances = ["Bob"];

E004: assignment to const variable before its declaration

You cannot reassign variables declared with const, and you cannot reference a variable declared with const above its declaration. The assignment will crash with a ReferenceError if you run the code.

let timeElapsed = 31;

let pie = "cooking";
if (timeElapsed > 30) {
  pi = "cooked";
}
const pi = 3.14;

To fix this error, assign to a different variable or declare a new variable with a different name:

let timeElapsed = 31;

let pie = "cooking";
if (timeElapsed > 30) {
  pie = "cooked";
}
const pi = 3.14;

See also: E001, E003

E005: BigInt literal contains decimal point

BigInt literals are number literals with an n suffix. These literals must represent integers and cannot contain a decimal point (.).

let gallons = 3.50n;
let pennies = 100.00n;

To fix this error, make the number literal a Number literal by removing the n suffix, or remove the fractional portion of the number:

let gallons = 3.50;
let pennies = 100n;

E006: BigInt literal contains exponent

BigInt literals are number literals with an n suffix. These literals must represent integers and cannot contain exponents (e).

let atomDiameter = 1e-10n;
let score = 1e2n;

To fix this error, make the number literal a Number literal by removing the n suffix, or expand the exponent of the number:

let atomDiameter = 1e-10;
let score = 100n;

E007: classes cannot be named 'let'

Classes declared with class cannot be named let.

class let {
  bark() {
    console.log("woof");
  }
}

To fix this error, name the class something other than let, or declare the class with var:

class Dog {
  bark() {
    console.log("woof");
  }
}

var let = class {
  bark() {
    console.log("woof");
  }
};

E008: let statement cannot declare variables named 'let'

Variables declared with let cannot be named let.

function getLotNumber() { return 42; }

let let = getLotNumber();
console.log(let);

To fix this error, name the variable something other than let, or declare the variable with var:

function getLotNumber() { return 42; }

let lot = getLotNumber();
console.log(lot);

var let = getLotNumber();
console.log(let);

E009: cannot export variable named 'let'

An exported function cannot be named let:

export function let() {
  console.log("access permitted");
}

To fix this error, name the function something other than let, or declare the function separately with a different name and use export-as:

export function allow() {
  console.log("access permitted");
}

function allowAccess() {
  console.log("access permitted");
}
export { allowAccess as let };

E010: cannot import 'let'

An imported function or variable cannot be named let:

import { let } from "./security.mjs";

To fix this error, name the function or variable something other than let, or rename the function or variable using import-as:

import { allow } from "./security.mjs";

import { let as permit } from "./security.mjs";

E012: escaped character is not allowed in identifiers

A function or variable name includes a Unicode escape sequence, and the escape sequence refers to a character which isn't allowed in a function or variable name:

let guitar\u2604 = "\uD83C\uDFB8";
let handc\uffed = true;

To fix this error, use the code point of a Unicode character which is allowed, or remove the extraneous backslash from the name:

let guitar\u3604 = "\uD83C\uDFB8";
let handcuffed = true;

The initial character in a function or variable name can be any of the following:

Characters after the initial character in a function or variable name can be any of the following:

E013: code point out of range

A function or variable name includes a Unicode escape sequence, and the escape sequence refers to a character which is beyond the range of valid Unicode code points (U+0000 to U+10FFFF):

class ChirpSound {}
let bird\u{360000} = new ChirpSound();

To fix this error, use the code point of a Unicode character which is in range:

class ChirpSound {}
let bird\u{3600} = new ChirpSound();

E014: expected expression before newline

throw statements cannot have a newline between the throw keyword and the thrown expression:

throw
  new Error(
    "something terrible happened!"
  );

To fix this error, add parentheses:

throw (
  new Error(
    "something terrible happened!"
  )
);

Alternatively, start the expression on the same line as the throw keyword:

throw new Error(
  "something terrible happened!"
);

E015: expected expression before semicolon

throw statements require an expression following the throw keyword. It is an error to rethrow an exception by writing just throw;:

try {
  goNuts();
} catch (e) {
  console.error(`couldn't handle deez nuts: ${e}`);
  throw;
}

function goNuts() {}

To rethrow an exception, name the exception variable after throw:

try {
  goNuts();
} catch (e) {
  console.error(`couldn't handle deez nuts: ${e}`);
  throw e;
}

function goNuts() {}

E016: expected hexadecimal digits in Unicode escape sequence

In variable names and strings, a Unicode escape sequence must contain only hexadecimal digits (any of 0123456789abcdefABCDEF). It is an error if other characters appear within a Unicode escape sequence:

console.log("List of Pok\ue9mon by weight:");
console.log("Nidoran\u{2642 {male}");

For an escape sequence without { and }, add { and }:

console.log("List of Pok\u{e9}mon by weight:");

Alternatively, for an escape sequence without { and }, include 0 digits such that the escape sequence contains exactly four hexadecimal digits:

console.log("List of Pok\u00e9mon by weight:");

For an escape sequence with { and }, ensure the } appears after the hexadecimal digits:

console.log("Nidoran\u{2642} {male}");

E017: if statement needs parentheses around condition

In JavaScript, if statements require parentheses around the condition. It is an error to omit the parentheses:

if 2 + 2 == 4 {
  console.log("Math works!");
}

To fix this error, add ( and ):

if (2 + 2 == 4) {
  console.log("Math works!");
}

E018: if statement is missing '(' or ')' around condition

An if statement is missing either ( before the condition or ) after the condition:

if (2 + 2 == 4 {
  console.log("Math works!");
}
if 4 == 2 + 2) {
  console.log("Jedi math works!");
}

To fix this error, add the missing ( or ):

if (2 + 2 == 4) {
  console.log("Math works!");
}
if (4 == 2 + 2) {
  console.log("Jedi math works!");
}

E019: invalid binding in let statement

const, let, and var can only declare variables directly or by destructuring an array or an object. Number literals and keywords are not allowed where a variable name is expected:

let wordCounts = {for: 4, if: 5, while: 0};
let {for, if} = wordCounts;

let queue = ["first", "second", "third"];
let {first: 0} = queue;

To fix this error when destructuring an object with keyword keys, pick a variable name which is not a keyword:

let wordCounts = {for: 4, if: 5, while: 0};
let {for: forWordCount, if: ifWordCount} = wordCounts;

When destructuring an object, it's common to confuse the variable name with the key. Make sure the variable name comes after the ::

let queue = ["first", "second", "third"];
let {0: first} = queue;

E063: missing operator between expression and arrow function

The left-hand side of => must be a list of parameters. It is a syntax error if the left-hand side looks like a function call:

let fs = require("fs");
let path = process.argv[2];
fs.readFile(path (err, data) => {
  console.log(data);
});

To fix this error, make the left-hand side of => valid by adding an operator (usually ,) before the parameter list:

let fs = require("fs");
let path = process.argv[2];
fs.readFile(path, (err, data) => {
  console.log(data);
});

E077: function call before declaration in blocked scope

A function can't be called before its declaration in block scope in Safari.

f();
{
    function f() {}
}

To fix this error, move the function call below the block scope in which it is declared:

{
    function f() {}
}
f();

Another way to fix this error, move the function out of the block scope in which it is declared.

f();
function f() {}
{
}

OR

f();
{
}
function f() {}

E086: redundant delete statement on variable

The following delete statement is redundant on variable:

let x = 3;
delete x;
console.log(x);

To fix this warning, remove the delete statement:

let x = 3;
console.log(x);

E095: Unicode byte order mark (BOM) cannot appear before #! at beginning of script

A script cannot have Unicode byte order mark (BOM) before #!

#!/usr/bin/env node
let x = 3;
console.log(x);

To fix this error, remove the Unicode BOM before #!

#!/usr/bin/env node
let x = 3;
console.log(x);

E133: error generator function star belongs before name

The following code has misplaced '*'.

*function f(x) { yield x; }

To fix this error, move the '*' before function name.

function *f(x) { yield x; }

E160: unexpected '=>'; expected parameter for arrow function, but got an expression instead

The left-hand side of => must be a list of parameters. It is a syntax error if the left-hand side is instead an expression (such as a property access or a function call):

if (this.mapSize => this.capacity) {
  throw new Error("too many items");
}

let fs = require("fs");
let path = process.argv[2];
fs.mkdir(path () => console.log("done"));

To fix this error, replace => with the intended operator, such as >=:

if (this.mapSize >= this.capacity) {
  throw new Error("too many items");
}

Alternatively, make the left-hand side of => valid by adding an operator (usually ,) before the parameter list:

let fs = require("fs");
let path = process.argv[2];
fs.mkdir(path, () => console.log("done"));

E164: JSON syntax error

quick-lint-js configuration files (named quick-lint-js.config or .quick-lint-js.config) contain valid JSON (according to RFC8259). quick-lint-js cannot read a configuration file with malformed JSON:

{
    "globals": {
        // Google Analytics
        "ga": true,
        "google": true,
    }
}

Common mistakes in JSON are trailing commas (disallowed) and comments (disallowed).

To fix this error, correct mistakes in the JSON syntax for your configuration file:

{
    "globals": {
        " // Google Analytics": false,
        "ga": true,
        "google": true
    }
}

E165: TypeScript style const field

const fields are only allowed in TypeScript, not JavaScript

class C {
  const f = null;
} 

To fix this error, remove the const declarator from the field

class C {
  f = null;
} 

E166: "globals" descriptor "shadowable" property must be a boolean

In a quick-lint-js configuration file, a entry in "globals" can have a descriptor object. A descriptor's "shadowable" property must be either true, false, or omitted.

{
    "globals": {
        "gsap": {
          "shadowable": 0
        }
    }
}

To fix this error, make the "shadowable" property true or false:

{
    "globals": {
        "gsap": {
          "shadowable": false
        }
    }
}

E167: "globals" descriptor "writable" property must be a boolean

In a quick-lint-js configuration file, a entry in "globals" can have a descriptor object. A descriptor's "writable" property must be either true, false, or omitted.

{
    "globals": {
        "gsap": {
          "writable": 0
        }
    }
}

To fix this error, make the "writable" property true or false:

{
    "globals": {
        "gsap": {
          "writable": false
        }
    }
}

E168: "globals" must be an object

In a quick-lint-js configuration file, "globals" must be an object or omitted. It is an error if "globals" is an array, a boolean, a number, a string, or null:

{
    "globals": [
        "ga",
        "google",
        "$"
    ]
}

To fix this error, make "globals" an object:

{
    "globals": {
        "ga": true,
        "google": true,
        "$": true
    }
}

E169: "global-groups" must be a boolean or an array

In a quick-lint-js configuration file, "global-groups" must be an array of strings, a boolean, or omitted. It is an error if "global-groups" is a boolean, a number, an object, a string, or null:

{
    "global-groups": {
        "ecmascript": true,
        "browser": true
    }
}

To fix this error, make "global-groups" an array:

{
    "global-groups": [
        "ecmascript",
        "browser"
    ]
}

E170: "global-groups" entries must be strings

In a quick-lint-js configuration file, items in the "global-groups" array must be strings. It is an error if an item is an array, a boolean, a number, an object, or null:

{
    "global-groups": [
        "ecmascript",
        2020,
        "browser"
    ]
}

To fix this error, remove non-string items in "global-groups":

{
    "global-groups": [
        "ecmascript",
        "browser"
    ]
}

E171: "globals" descriptor must be a boolean or an object

In a quick-lint-js configuration file, each entry in "globals" must be a boolean or a descriptor object. It is an error if a "globals" item is an array, a number, a string, or null:

{
    "globals": {
        "gsap": "true"
    }
}

To fix this error, make the "globals" entry true or false:

{
    "globals": {
        "gsap": true
    }
}

E202: missing '=' after variable

The following code has a missing equal '=' after variable name.

let x new Array();

To fix this error, add '=' after variable x.

let x = new Array();

E204: error generator function star belongs after keyword function

The following code has misplaced '*'.

let x = *function(y) { yield y; };

To fix this error, move the '*' after the keyword function.

let x = function*(y) { yield y; };

E205: error missing initializer in const declaration

The following code is missing initialization for const variable declaration.

const x;

To fix this error, initialize the variable x with some value.

const x = 10;

Another way to fix this error, change const to let.

let x;

E206: error label named await not allowed in async function

The following code is using label named 'await' in an async function.

async function f() {
  await:
}

To fix this error, rename label await to something else.

async function f() {
  label:
}

Another way to fix this error, make 'f' a normal function rather than an async function.

function f() {
  await:
}

E207: code point in Unicode escape sequence must not be greater than U+10FFFF

The following code has escaped code point in Unicode out of range.

let x = "hello\u{abcdef}";

To fix this error, make sure that the escaped code point is between U+0000 and U+10FFFF inclusive.

let x = "hello\u{abcde}";

E208: cannot access private identifier outside class

The following code is accessing a private identifier outside the class.

class C {
  #x = 10;
}

function f(c) {
  c.#x = 20;
}

To fix this error, move function f as a static member of class C .

class C {
  #x = 10;
  static f(c) {
    c.#x = 20;
  }
}

Another way to fix this error, remove # before variable x.

class C {
  x = 10;
}

function f(c) {
  c.x = 20;
}