Return Value Ignored

ID

javascript.return_value_ignored

Severity

low

Remediation Complexity

trivial

Remediation Risk

low

Remediation Effort

low

Resource

Reliability

Language

JavaScript

Tags

dead-code, reliability

Description

Reports a call to a well-known pure built-in whose return value is discarded because the call stands alone as a whole expression statement: name.trim();, items.filter(isReady);, Object.keys(config);.

JavaScript has no types the engine can lean on here, so purity comes from two curated lists rather than from inference, and both are deliberately narrow.

  • Static built-ins are matched on the namespace and the method: Math, JSON, Object, Number, Array and String. Naming the namespace makes these effectively certain. The mutating members of those namespaces are absent by design — Object.assign, Object.freeze, Object.defineProperty and Object.setPrototypeOf all change the object handed to them, so ignoring what they return is correct.

  • Instance methods are matched on the method name alone, and only on a member call: x.trim(), never a bare trim(s), which would be some local helper. The list holds only names whose mutating counterparts are spelled differently — the in-place array methods sort, reverse, splice, push, fill and copyWithin are not on it, while their copying siblings toSorted, toReversed and slice are. normalize is left off for the same reason: on a DOM node it merges text children in place.

The call also has to be the last link of its chain and the whole expression of the statement, so items.filter(isReady).forEach(run); and count = items.filter(isReady).length; are not reported — the filtered array is used.

Rationale

// Bad
function normalizeName(name) {
  name.trim();               // returns a trimmed copy; `name` is untouched
  return name;
}

function readyCount(items, isReady) {
  items.filter(isReady);     // returns a new array, dropped on the floor
  return items.length;
}
  • These operations compute a new value and leave the receiver and the arguments alone, so a statement that drops the result does nothing at all. The line reads as if it changed something, which is why it survives review.

  • JavaScript’s string methods are all non-mutating — strings are immutable — so every s.someMethod(); statement on a string is dead code.

  • The array API is the trap: sort and reverse mutate in place, map, filter and slice return a copy. Half the methods reward the statement form and half do not, and nothing in the call site says which.

  • items.filter(f); written for the side effects of f is the specific mistake forEach exists to avoid.

Remediation

Use the returned value, or switch to the operation that changes the receiver.

// Good
function normalizeName(name) {
  return name.trim();
}

function readyCount(items, isReady) {
  return items.filter(isReady).length;
}

function run(items, effect) {
  items.forEach(effect);     // the effectful sibling of `map`
}

If the call really is there only for a side effect inside a callback, for…​of or forEach says so; if the value is genuinely unwanted, deleting the statement is the honest fix.

© 2026 Xygeni. All rights reserved