ReferenceError: can't access lexical declaration 'X' before initialization

The JavaScript exception "can't access lexical declaration `variable' before initialization" occurs when a lexical variable was accessed before it was initialized. This happens within any block statement, when let or const variables are accessed before the line in which they are declared is executed.

Message

ReferenceError: Cannot access 'X' before initialization (V8-based)
ReferenceError: can't access lexical declaration 'X' before initialization (Firefox)
ReferenceError: Cannot access uninitialized variable. (Safari)

Error type

What went wrong?

A lexical variable was accessed before it was initialized. This happens within any block statement, when variables declared with let or const are accessed before the line in which they are declared has been executed.

Note that it is the execution order of access and variable declaration that matters, not the order in which the lines appear in the code. For more information, see the description of Temporal Dead Zone.

This issue does not occur for variables declared using var, because they are initialized with a default value of undefined when they are hoisted.

This error can also occur in cyclic imports when a module uses a variable that depends on the module itself being evaluated.

Examples

Invalid cases

In this case, the variable foo is accessed before it is declared. At this point foo has not been initialized with a value, so accessing the variable throws a reference error.

js

function test() {
  // Accessing the 'const' variable foo before it's declared
  console.log(foo); // ReferenceError: foo is not initialized
  const foo = 33; // 'foo' is declared and initialized here using the 'const' keyword
}

test();

In this example, the imported variable a is accessed but is uninitialized, because the evaluation of a.js is blocked by the evaluation of the current module b.js.

js

// -- a.js (entry module) --
import { b } from "./b.js";

export const a = 2;

// -- b.js --
import { a } from "./a.js";

console.log(a); // ReferenceError: Cannot access 'a' before initialization
export const b = 1;

Valid cases

In the following example, we correctly declare a variable using the const keyword before accessing it.

js

function test() {
  // Declaring variable foo
  const foo = 33;
  console.log(foo); // 33
}
test();

In this example, the imported variable a is asynchronously accessed, so both modules are evaluated before the access to a occurs.

js

// -- a.js (entry module) --
import { b } from "./b.js";

export const a = 2;

// -- b.js --
import { a } from "./a.js";

setTimeout(() => {
  console.log(a); // 2
}, 10);
export const b = 1;

See also