swc-project/swc · error

Duplicate variable name: {ident_str}

Error message

Duplicate variable name: {ident_str}

What it means

Within one quote! invocation, each interpolated variable name may be bound exactly once: the macro records every name in an init map and panics with 'Duplicate variable name: {ident_str}' when a name is inserted twice. Even binding the same name with two different type annotations triggers it.

Source

Thrown at crates/swc_ecma_quote_macros/src/ctxt.rs:135

                    var.ty
                )
            }
        };

        let var_ident = syn::Ident::new(&format!("quote_var_{ident}"), ident.span());

        let old = init_map.entry(pos).or_default().insert(
            ident_str.clone(),
            VarData {
                pos,
                is_counting: true,
                clone: Default::default(),
                ident: var_ident.clone(),
            },
        );

        if let Some(old) = old {
            panic!("Duplicate variable name: {ident_str}");
        }

        let type_name = Ident::new(
            match pos {
                VarPos::Ident => "Ident",
                VarPos::Expr => "Expr",
                VarPos::Pat => "Pat",
                VarPos::AssignTarget => "AssignTarget",
                VarPos::Str => "Str",
            },
            call_site(),
        );
        stmts.push(parse_quote! {
            let #var_ident: swc_core::ecma::ast::#type_name = #value;
        });
    }

    // Use `ToCode` to count how many times each variable is used.

View on GitHub (pinned to 5176682b65)

Solutions

  1. Rename one of the duplicate interpolations so each name binds once per quote! block
  2. If the same value is needed twice, bind it once and reference the generated quote_var_* identifier, or split into two quote! invocations
  3. Grep the macro body for the reported identifier to find both binding sites quickly

Example fix

// before
quote!(name as Ident; name as Expr; log(name););

// after
quote!(name as Ident; expr as Expr; log(name, expr););
Defensive patterns

Strategy: validation

Prevention

When it happens

Trigger: Writing quote!(name as Ident; name as Expr;) or repeating an interpolation binding for the same variable name inside a single quote! block.

Common situations: Large hand-written quote blocks edited over time where a variable gets interpolated twice, copy-paste of interpolation statements, refactors that rename one binding but leave a stale duplicate.

Related errors


AI-assisted analysis of swc-project/swc@5176682b65 (2026-08-17). Data as JSON: /api/errors/e79f007c170dca79. Report an issue: GitHub.