8000 Fix sum/sumBy/mean/meanBy to return NaN for non-numeric values (fixes #5818) by flavioespinoza · Pull Request #6095 · lodash/lodash · GitHub
[go: up one dir, main page]

Skip to content

Conversation

@flavioespinoza
Copy link

Summary

Fixes #5818 where sumBy returns string concatenation ('1fnull') instead of a numeric value when encountering non-numeric values.

Changes

  • Add internal isNumeric function to validate numeric values
  • Add internal describeType function for detailed type descriptions in warnings
  • Modify baseSum to return NaN and emit a descriptive console.warn for non-numeric values
  • Update JSDoc documentation for sum, sumBy, mean, meanBy
  • Add comprehensive tests for all non-numeric types

Behavior

Before:

_.sumBy([{ a: 1 }, { a: 'f' }, { a: null }], 'a')
// => '1fnull' (string concatenation - bug)

After:

_.sumBy([{ a: 1 }, { a: 'f' }, { a: null }], 'a')
// => NaN
// Console: "lodash: sum/sumBy encountered non-numeric value at index 1.
//          Expected number, got string "f". Returning NaN."

Why NaN + Warning (not TypeError)

  • Matches lodash's forgiving philosophy (doesn't crash)
  • Returns NaN as requested in Method sumBy returns string  #5818
  • Console warning provides debugging info without breaking existing code
  • Backwards compatible - apps won't crash, just get NaN (which is typeof 'number')

Types Covered

Value Warning Message
'hello' string "hello"
[1,2,3] array
{foo: 'bar'} object
function myFunc(){} function myFunc()
null null
true boolean
new Date() Date

Test Plan

  • npm run build passes
  • npm test passes (6808 + 327 = 7135 tests)
  • All non-numeric types return NaN with descriptive warning

Not Affected (intentionally)

min, max, minBy, maxBy - these legitimately support comparing any comparable values (strings alphabetically, dates chronologically).

🤖 Generated with Claude Code

…odash#5818)

- Add internal `isNumeric` function to validate numeric values
- Add internal `describeType` function for detailed type descriptions
- Modify `baseSum` to return NaN and emit console warning for non-numeric values
- Update JSDoc with comprehensive documentation

**Behavior:**
- Returns `NaN` for non-numeric values (matches issue lodash#5818 expected behavior)
- Emits descriptive console.warn with:
  - Index where non-numeric value was found
  - Type description (string "hello", array, object, function myFunc(), null, etc.)

**Examples:**
```javascript
_.sumBy([{ a: 1 }, { a: 'hello' }], 'a')
// => NaN
// Console: "lodash: sum/sumBy encountered non-numeric value at index 1.
//          Expected number, got string "hello". Returning NaN."

_.sumBy([{ a: 1 }, { a: [1,2,3] }], 'a')
// => NaN
// Console: "lodash: sum/sumBy encountered non-numeric value at index 1.
//          Expected number, got array. Returning NaN."
```

**Affected functions:**
- `sum`, `sumBy`, `mean`, `meanBy`

**Not affected (intentionally):**
- `min`, `max`, `minBy`, `maxBy` - support comparing any comparable values

Fixes lodash#5818

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Comment on lines -21575 to +21604
assert.strictEqual(func(['1', '2']), '12');
assert.ok(isNaN(func(['1', '2'])), 'returns NaN for string values');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this constitutes a breaking change.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Totally understand the breaking change concern - lodash's reach means even bug fixes need careful consideration.

I can revert this change if needed. But I'm genuinely curious about the philosophy here:

Who is intentionally relying on _.sum(['1', '2']) returning '12'?

It's a Math function documented to return a number. If someone passes ['1', '2'] and gets string concatenation, that's almost certainly a bug in their code that's being silently masked. Returning NaN (or even coercing '1'1) would help them find that bug.

I get that semver is semver, but is there a threshold where "fixing a clear contract violation" doesn't require a major bump? Or would you suggest an alternative approach - maybe coercing numeric strings to numbers instead of returning NaN?

By the way - the reason I'm putting effort into this PR is because lodash is my favorite library ever. I'd guess it's the most used library on npm (you'd know better than me). I remember my frustration with underscore back in the day, and lodash was a game-changer. I actually created a library called 8000 datedash inspired by the lodash style for date formatting.

If there's a way around this, or a way through it, it would genuinely be an honor to contribute to lodash. Happy to adjust or withdraw - just want to understand the path forward.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hopefully nobody's relying on it :-)

that said, it still should wait until a v5. In the meantime, it would be better to have a PR that adds tests for the current behavior, and updates the docs to match.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

flavioespinoza added a commit to flavioespinoza/lodash that referenced this pull request Jan 27, 2026
…odash#5818)

Update JSDoc and add tests to document the current behavior where non-numeric
values in sum/sumBy/mean/meanBy result in string concatenation rather than
numeric addition.

This documents the existing behavior as reported in lodash#5818. The behavior may
change in a future major version (see lodash#6095 for the proposed fix).

Changes:
- Update JSDoc for sum, sumBy, mean, meanBy to note string concatenation behavior
- Update @returns to reflect that string may be returned
- Add examples showing the non-numeric behavior
- Add tests documenting string concatenation with various non-numeric inputs
- Reference lodash#5818 in documentation

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Method sumBy returns string

2 participants

0