Skip to main content

How to Resolve ESLint Error "Arrow function should not return assignment" (no-return-assign) in JavaScript

The ESLint error Arrow function should not return assignment (rule: no-return-assign) is designed to prevent a common source of bugs and confusing code: performing a variable assignment inside a return statement. This is often an unintentional typo (= instead of ===) or a coding pattern that makes the function's intent unclear.

This guide will explain why this error occurs and provide the clear, correct solutions. You will learn how to properly separate assignments from return statements and how to distinguish between an assignment (=) and a comparison (===).

Understanding the Root Cause: Implicit vs. Explicit Return

This error most often occurs with arrow functions because of their concise, "implicit return" syntax. When an arrow function's body is not enclosed in curly braces {}, the result of the expression is automatically returned.

The Error in Action (Implicit Return)

let myVar = 10;

// ⛔️ Arrow function should not return assignment. (eslint no-return-assign)
const updateVar = () => (myVar = 20);

Here, the arrow function's body is just the assignment myVar = 20. The result of an assignment expression is the assigned value itself (in this case, 20). So, this function is unintentionally returning 20. ESLint flags this because it's ambiguous and often a bug.

The Error in Action (Explicit Return)

The same error occurs with a traditional return statement.

let myVar = 10;

function updateVar() {
// ⛔️ Return statement should not contain assignment. (eslint no-return-assign)
return (myVar = 20);
}

Solution 1 (Most Common): Use a Block Body for Arrow Functions

If your goal is to perform an action (a "side effect"), like modifying a variable, and not to return a value, you should use a block body (curly braces {}) for your arrow function.

The problem:

// This function implicitly returns the result of the assignment.
const updateVar = () => (myVar = 20);

The solution:

let myVar = 10;

// This function performs the assignment and implicitly returns 'undefined'.
const updateVar = () => {
myVar = 20;
};

// No error is thrown.
updateVar();
console.log(myVar); // Output: 20
note

By using curly braces, you create a function body, and the assignment is just a statement within it. The function no longer returns the assignment's value.

Solution 2: Separate the Assignment and Return Statements

If your goal is to both assign a value and return it (a common pattern in methods like Array.prototype.reduce), you must do so in two separate, clear steps.

The Problematic Code:

const result = arr.reduce((acc, obj) => (acc[obj.id] = obj), {});
// ⛔️ Arrow function should not return assignment.

The solution:

const arr = [
{ id: 1, name: 'Alice' },
{ id: 2, name: 'Bob' },
];

const result = arr.reduce((accumulator, obj) => {
// Step 1: Perform the assignment (mutation)
accumulator[obj.id] = obj;

// Step 2: Explicitly return the accumulator
return accumulator;
}, {});

console.log(result);
// Output: { '1': { id: 1, name: 'Alice' }, '2': { id: 2, name: 'Bob' } }
note

This code is much clearer about its intent: it first modifies the accumulator and then returns it.

A Common Mistake: Assignment (=) vs. Comparison (===)

This ESLint rule is excellent at catching a very common type of bug: using a single equals sign (=) for an assignment when you meant to use a double or triple equals (== or ===) for a comparison.

The Buggy Code:

function isPositive(num) {
// ⛔️ Return statement should not contain assignment.
// This code has a bug: it assigns 0 to num, and then returns 0 (a falsy value).
return num = 0;
}

The fix is by using the correct comparison operator.

function isPositive(num) {
// ✅ Correctly checks if num is greater than 0.
return num > 0;
}

How to Disable the no-return-assign Rule (When Necessary)

While it's highly recommended to fix the underlying code, you can disable the ESLint rule if you have a specific reason.

For a Single Line

// eslint-disable-next-line no-return-assign
const example = () => (myVar = 200);

For an Entire File

Place this comment at the top of your file.

/* eslint-disable no-return-assign */

In Your .eslintrc.js File (Globally)

module.exports = {
// ...
rules: {
'no-return-assign': 'off',
// ...
},
};

Conclusion

The no-return-assign ESLint rule is a valuable safeguard against ambiguous code and common bugs.

To fix it:

  • If you intend to perform a side effect, use a block body ({...}) in your arrow function to avoid an implicit return.
  • If you intend to assign and return, do it in two separate statements.
  • Double-check your code to ensure you haven't accidentally used an assignment operator (=) where you meant to use a comparison (===).

By following these best practices, you can write clearer, more intentional, and less error-prone code.