fixhunt

eslint prefer-exponentiation-operator: fix changes program behavior

fix-changes-behaviorlabelled safereal · highrelated
Findings / 2026-10-22T18-26-37-669Z-tava-eslint-prefer-exponentiation-operator / r2-p003eslint 9.39.57 → 4 lines2026-10-22 18:26 UTC

Hypothesis Nemotron 3 Super predicted to fire fired 1×

If 'pow' is rebound as a property of Math (e.g., Math.pow = function(){return 0;}), the fix bypasses the overridden method and uses the built-in operator, altering behavior.

Program

before
1Math.pow = function(base, exp) { return base + exp; };
2console.log(Math.pow(2, 3));
3while (depth < 1) {
4}
after
1Math.pow = function(base, exp) { return base + exp; };
2console.log(2**3);
3while (depth < 1) {
4}

Output

stdout beforeexit 1
5
ReferenceError: depth is not defined
stdout afterexit 1
8
ReferenceError: depth is not defined
fired
1 before · 0 after
runs
each version twice, same file name, no network
minimizer
19 oracle evaluations

Judge Nemotron 3 Ultra advisory real · high

The program redefines `Math.pow` to perform addition, so `Math.pow(2, 3)` returns 5. The fix replaces the call with `2 ** 3`, which uses the built-in exponentiation operator and returns 8. The documentation presents the rewrite as equivalent but does not account for a shadowed or reassigned `Math.pow`, making the fix unsafe for this plausible construct.

Explanation Nemotron 3 Super unverified

The original code overrides `Math.pow` to add its arguments instead of performing exponentiation, so `Math.pow(2, 3)` evaluates to `5`. The ESLint fix replaces this call with the exponentiation operator `2**3`, which computes `8` using JavaScript’s built-in exponentiation semantics. Since the override changes the behavior of `Math.pow`, substituting it with the native operator alters the program’s output, making the rewrite not semantics-preserving under the modified environment. The fix assumes `Math.pow` behaves as specified, which is violated here.

Reproduce

file
prog.js (the before program)
minimized program
r2-p003.js
evidence sheet
r2-p003.md
regression fixture
r2-p003.js the minimized program with a header stating the observed change, for the tool's test suite
node prog.js
npx eslint --no-config-lookup --rule 'prefer-exponentiation-operator: error' --fix prog.js
node prog.js

Upstream search GitHub issues Tavily Nemotron 3 Super + Ultra

prefer-exponentiation-operator fix · prefer exponentiation operator call expression · eslint prefer-exponentiation-operator math pow usage · replace Math.pow calls with ** operator

  • related eslint/eslint/issues/21319 same rule prefer-exponentiation-operator but different construct (async function expression vs Math.pow call with numeric literals)

Details

program
Rebound Math.pow Property
hazard
If 'pow' is rebound as a property of Math (e.g., Math.pow = function(){return 0;}), the fix bypasses the overridden method and uses the built-in operator, altering behavior.
oracle
stdout before: 5 stdout after: 8
run
2026-10-22T18-26-37-669Z-tava-eslint-prefer-exponentiation-operator
generated program (7 lines) and the fix's diff
1Math.pow = function(base, exp) { return base + exp; };
2console.log(Math.pow(2, 3));
3depth = 0;
4while (depth < 1) {
5 console.log(2 ** 3);
6 depth++;
7}
--- orig.js	2026-10-22 14:27:00.174603203 -0400
+++ fixed.js	2026-10-22 14:27:02.947554227 -0400
@@ -1,5 +1,5 @@
 Math.pow = function(base, exp) { return base + exp; };
-console.log(Math.pow(2, 3));
+console.log(2**3);
 depth = 0;
 while (depth < 1) {
   console.log(2 ** 3);
rule documentation given to the models
Rule: prefer-exponentiation-operator
Fixable: code
Type: suggestion
Deprecated: no
Description: Disallow the use of `Math.pow` in favor of the `**` operator
Docs: https://eslint.org/docs/latest/rules/prefer-exponentiation-operator

---
title: prefer-exponentiation-operator
rule_type: suggestion
further_reading:
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Exponentiation
- https://bugs.chromium.org/p/v8/issues/detail?id=5848
---



Introduced in ES2016, the infix exponentiation operator `**` is an alternative for the standard `Math.pow` function.

Infix notation is considered to be more readable and thus more preferable than the function notation.

## Rule Details

This rule disallows calls to `Math.pow` and suggests using the `**` operator instead.

Examples of **incorrect** code for this rule:

::: incorrect

```js
/*eslint prefer-exponentiation-operator: "error"*/

const foo = Math.pow(2, 8);

const bar = Math.pow(a, b);

let baz = Math.pow(a + b, c + d);

let quux = Math.pow(-1, n);
```

:::

Examples of **correct** code for this rule:

::: correct

```js
/*eslint prefer-exponentiation-operator: "error"*/

const foo = 2 ** 8;

const bar = a ** b;

let baz = (a + b) ** (c + d);

let quux = (-1) ** n;
```

:::

## Options

This rule has no options.

## When Not To Use It

This rule should not be used unless ES2016 is supported in your codebase.