# “SyntaxError: Identifier 'x' has already been declared”

> SyntaxError: Identifier 'x' has already been declared. Two let or const with one name in a scope, an import clash, a switch case, or a script loaded twice.

Canonical: https://app369.com/fix/identifier-has-already-been-declared/
Last updated: 2026-11-08

The script does not run at all and the console shows SyntaxError: Identifier 'user' has already been declared (Chrome, Node.js) or Cannot declare a let variable twice: 'user' (Safari). A let, const or class tried to reuse a name that already exists in the same scope. Because it is a syntax error, nothing in that file runs, not even the lines before it.

**Short answer**

Find the two declarations of the name in the message. If they are in the same block, rename one or drop the second let or const and assign to the first. If one is an import, rename the local variable or import with as. In a switch, wrap each case in braces. In the browser, if the file is fine, the same script is probably loaded twice, or two classic scripts declare the same top-level name.

## **Why the name is taken, and the fix**

1. 01 ### **Two declarations in the same scope**
  > “let declarations cannot be in the same scope as any other declaration, including let, const, class, function, var, and import declaration.” [**MDN, let: Redeclarations**](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let) Often from pasting code, or an AI edit that added a block without removing the old one. Keep one declaration and assign to it.```
// wrong
let total = 0;
let total = items.length;

// right
let total = 0;
total = items.length;
```
2. 02 ### **A local name that clashes with an import or a parameter**
  > “A let declaration within a function's body cannot have the same name as a parameter.” [**MDN, let: Redeclarations**](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let) import { user } from './store' and then const user = ... in the same module, or a function parameter redeclared with let. Rename the local value, or import under another name.```
import { user as storeUser } from './store';
const user = storeUser ?? guest;
```
3. 03 ### **The same name in two switch cases**
  > “To avoid the error, wrap each case in a new block statement.” [**MDN, let: Redeclarations**](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let) All cases of a switch share one block, so let message in two cases is a redeclaration.```
switch (status) {
  case 'ok': {
    const message = 'Saved';
    break;
  }
  case 'error': {
    const message = 'Try again';
    break;
  }
}
```
4. 04 ### **A script loaded twice, or two scripts using one name**
  > “if you declare a let or const variable in the first script, declaring it again in the second script will cause a redeclaration error.” [**MDN, let: Temporal dead zone**](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let) Classic script tags share one top-level scope. If a page includes the same file twice, or two files both declare const API_URL at the top level, the second one throws. Load the file once, or make the scripts modules (type="module"), which each get their own scope. Modules also stop top-level names becoming globals, so check that nothing reads them from window.```
<script type="module" src="/js/app.js"></script>
```

Checked against the vendor’s docs on November 8, 2026: [MDN: let](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let).

## **Rather hand it over?**

Fixed scope, fixed price, paid upfront. The work happens in writing; no call needed.

- [from $450**App Fix Ticket**One reproducible bug in an existing mobile or web app, diagnosed and fixed.**See scope and start**](https://app369.com/fixed-price/flutter-firebase-bug-fix/)
- [from $450**AI-Built App Rescue**A Lovable, Bolt or Cursor app checked end to end in 3 days, then its worst problems fixed at a fixed price.****No issues worth fixing, no charge.**** If the Launch Check finds nothing rated medium or higher, Simon refunds the full $450. You keep the report either way. This applies to the first 10 Launch Checks bought after October 30, 2026.**See scope and start**](https://app369.com/fixed-price/ai-app-rescue/)

Related: [**JavaScript “x is not defined”**](https://app369.com/fix/javascript-is-not-defined/) · [**“Unexpected identifier”**](https://app369.com/fix/unexpected-identifier/) · [**“Invalid or unexpected token”**](https://app369.com/fix/invalid-or-unexpected-token/)

Questions

## **More on this error**

<details>

<summary>**Why does var not give this error? **+</summary>

var allows a second declaration of the same name and quietly reuses the variable. let, const and class do not, which is how they catch this mistake.

</details>

<details>

<summary>**Why does it happen in the browser console? **+</summary>

Console entries share the page’s top-level scope. Firefox’s console throws when a later entry declares the same let again; Chrome’s console allows let redeclarations between entries. Wrap experiments in braces to give them their own block.

</details>

<details>

<summary>**Can you fix it for me? **+</summary>

If one bug is the whole problem, the App Fix Ticket covers it: a written diagnosis first, then the fix. If the app has more going on, the Launch Check is a written check of the whole app. Each issue found is rated critical, high, medium or low, with where it is and how it was confirmed. No issues worth fixing, no charge. If the Launch Check finds nothing rated medium or higher, Simon refunds the full $450. You keep the report either way. This applies to the first 10 Launch Checks bought after October 30, 2026.

</details>

A different error?

## **Describe it and get a written quote**

Send the error and what you were doing. You get a written scope, a fixed price and a timeline; Simon replies by email, usually within one business day.

[**Describe your problem **→](https://app369.com/contact/) [**All fixes**](https://app369.com/fix/)