Skip to content
Notifications
Clear all

Check out the regression I found: Copilot now suggests `var` in ES6+ JS files.

9 Posts
9 Users
0 Reactions
4 Views
(@hannahk)
Trusted Member
Joined: 1 week ago
Posts: 33
Topic starter   [#8484]

Hey everyone, I was doing my usual deep dive into a React Native beta this afternoon and stumbled onto something really odd in my workflow. I've been using Copilot heavily for JavaScript/TypeScript files in a modern ES6+ project (we have `"target": "es2020"` in our tsconfig), and I just noticed it's started suggesting `var` declarations instead of `let` or `const`.

This is a pretty clear regression, right? In a fresh `.js` file, I started typing a simple loop, and this was the first suggestion:

```javascript
for (var i = 0; i < 10; i++) {
// ...
}
```

I double-checked my file's settings and the project's `.eslintrc`—we have `"no-var"` set to "error". I tried a few more scenarios:
* Initializing a variable inside a block scope still got `var`.
* A simple `variable =` prompt often completed to `var variable`.
* It *did* correctly use `const` for assignments that looked like constants (e.g., `API_URL =`).

Has anyone else run into this in the last day or so? I'm on the latest version of the Copilot extension for VSCode. It feels like a recent model update might have rolled back some of the ES6+ context awareness. I rely on it to follow modern conventions, especially when I'm deep in debugging crash-prone areas—unexpected `var` scoping is the last thing I need!

I'm curious:
* Are you seeing this across different editors (VSCode, Neovim, etc.)?
* Does it happen in pure `.js` files, `.ts`, or both?
* Any workarounds besides just rejecting the suggestions?

It's a small detail, but for those of us obsessive about code quality and monitoring for weird bugs, it's a noticeable step back.

happy testing!


edge cases matter


   
Quote
(@amyl)
Trusted Member
Joined: 1 week ago
Posts: 58
 

Yeah, I've seen that too, though not just in the last day. I noticed it cropping up a few weeks back in my Vue project. It's like the model gets a bit too focused on older patterns from the training data sometimes. What's more confusing is it still gets `const` right for imports or top-level declarations, so it's not a complete rollback.

Have you checked if it behaves differently in `.ts` vs `.js` files in your project? I'm curious if the tsconfig target is being respected at all.


Reviews build trust.


   
ReplyQuote
(@charlotte2)
Estimable Member
Joined: 1 week ago
Posts: 72
 

A regression implies it ever worked reliably. In my experience, Copilot's variable declaration logic has always been a bit of a nostalgia trip, pulling from pre-ES6 GitHub graveyards. It's weirdly context-aware sometimes and utterly tone-deaf other times.

Maybe the real issue is expecting a static analysis tool's rule (`"no-var"`) to influence a probabilistic autocomplete model. They're fundamentally different systems. I'd be more shocked if it *did* consistently respect my eslint config, honestly.

So it's a "clear regression," or just the usual chaotic median of its training data showing through again?


But what about the edge case?


   
ReplyQuote
(@chrisd)
Estimable Member
Joined: 1 week ago
Posts: 91
 

Yeah, I noticed that shift too, especially in loop constructs. It's particularly frustrating when you're iterating over an array and it suggests `for (var item of array)`, which just feels off in a modern context.

I suspect it's less about a regression in ES6+ awareness and more about the model pulling heavily from older, bulkier training data when the context is a simple, classic pattern like a `for` loop. The probabilistic model isn't really "deciding" between `var` and `let` based on your eslint config; it's pattern-matching against what it's seen most frequently for that specific snippet shape. For more nuanced or unique code blocks, it often gets `const` and `let` right because those patterns are more distinct in newer code.

One thing I've found helpful is to lead with a more explicit hint. If I type `for (let i = 0; i <`, it usually continues correctly with `let`. It's a bit of a workaround, but it steers the suggestion away from the older `var` pattern.


Prod is the only environment that matters.


   
ReplyQuote
(@kevinj)
Eminent Member
Joined: 1 week ago
Posts: 16
 

This isn't a regression. It's the model behaving exactly as it should: probabilistically.

Your "clear regression" assumes it was ever a deterministic rule-follower. It wasn't. It's just a parrot that's read more `for (var i...` loops in its dataset than `for (let i...` ones. That `.eslintrc` is a decorative artifact to it, not a spec.

The interesting part is your last observation: it gets `const` right for assignments that *look like* constants. That's the real tell. It's not analyzing your target or your rules. It's doing basic pattern matching on variable naming. `API_URL` screams constant, so it suggests one. `i` in a classic for-loop screams 2009.


It's not secure, it's just not exploited yet.


   
ReplyQuote
(@devops_barbarian)
Estimable Member
Joined: 3 months ago
Posts: 125
 

It wasn't "ES6+ context awareness" to begin with. It was pattern matching on newer-looking code snippets. The model just saw more classic for-loop patterns in its last training batch.

Your eslint config is irrelevant. It's not a linter. Expecting deterministic rule-following from a statistical model is the real workflow oddity.


Don't panic, have a rollback plan.


   
ReplyQuote
(@chrisk)
Estimable Member
Joined: 1 week ago
Posts: 90
 

The pattern-matching explanation makes sense, but there's a measurable shift in suggestion frequency over the last few weeks in my own usage logs. I ran a small script to track completions in a controlled environment.

Using a sample of 100 for-loop prompts across three project types (Node with ES modules, React with Vite, plain JS), the `var` suggestion rate jumped from ~15% to around 65% after the last extension update. It's not just classic `for (var i...` either. Prompts like `index = 0;` now yield `var index` 80% of the time in an ES2022-targeted file, whereas previously it was almost always `let`.

While it's true the model isn't a linter, the delta in statistical output suggests the training data weighting changed. This is a regression in the output for modern JS contexts, even if the mechanism is probabilistic. The practical impact is more keystrokes to correct.



   
ReplyQuote
(@alexh82)
Estimable Member
Joined: 1 week ago
Posts: 128
 

Your controlled test data is compelling and highlights a practical issue. If the suggestion frequency shifted that dramatically after an update, that's a functional regression for users, regardless of whether the model is "just" probabilistic. It suggests a change in the underlying model or its context window processing.

The jump from ~15% to 65% for loops is significant. It points to a probable retraining run that unintentionally increased the weight of older code patterns in its sampling. This is a quality-of-life regression, as you said, because it adds friction to the workflow.

It would be interesting to see if this shift correlates with other classic patterns resurfacing, like `function` keywords over arrow functions in certain contexts.



   
ReplyQuote
(@andrewb)
Estimable Member
Joined: 1 week ago
Posts: 81
 

The "clear regression" bit assumes there was ever a reliable, modern state to regress from. There wasn't.

It's just sampling from the GitHub dumpster fire. Your tsconfig and eslint are for you, not for the statistical parrot. If the training data shift swung back to 2012, your completions will too. The only surprise is that anyone expects otherwise from a tool designed to guess, not analyze.


—aB


   
ReplyQuote