How to Fix a JavaScript Number Concatenation Bug

String amounts summed with + silently concatenate instead of adding - '10' + '5' is '105', not 15. The fix is to coerce each value to a number before the sum. It's a silent bug: no error, just a wrong result.

Fullstack Engineerfullstacktype-coercionnumbers

Why + concatenates instead of adds

JavaScript's + operator is overloaded: when both operands are numbers it adds, but when either operand is a string it concatenates. Form fields, query strings, and JSON payloads from certain clients deliver values as strings - so + does the wrong thing silently.

// All three values arrive as strings from a form or JSON body:
const amounts = ["10", "5", "3"];
const total = amounts[0] + amounts[1] + amounts[2];
// total === "1053"  -- string concatenation, not addition

No exception is thrown. The endpoint returns something, just the wrong something - which makes this one of the harder bugs to notice without a targeted test.

The fix: coerce before you sum

Convert each value to a number before accumulating. Python and JavaScript both have the same trap; both have the same fix.

Python (Flask endpoint):

@app.post("/api/total")
def total():
    amounts = (request.get_json(silent=True) or {}).get("amounts", [])
    result = sum(int(a) for a in amounts)
    return jsonify(total=result)

int(a) (or float(a)) converts each string before the sum - sum(...) then adds numbers, not strings.

JavaScript equivalent:

const amounts = ["10", "5", "3"];

// Option 1: unary + (coerces to number)
const total = amounts.reduce((acc, a) => acc + +a, 0);

// Option 2: explicit Number()
const total2 = amounts.reduce((acc, a) => acc + Number(a), 0);

// Option 3: parseInt / parseFloat
const total3 = amounts.reduce((acc, a) => acc + parseInt(a, 10), 0);

Starting the accumulator at 0 (a number) is important: if you start with "" or omit the initial value when the first element is a string, you're back to concatenation.

Validate at the boundary

The most reliable defense is to validate and coerce incoming data the moment it enters your system - before any business logic runs:

Want to try it hands-on? HeyDevJob gives you this exact setup in a live cloud workspace in your browser - edit it, run it, and see it work. Free, nothing to install.

Try it in a workspace →

What you'll practice

FAQ

Why does my JavaScript total concatenate instead of add?

Because the values are strings and the + operator concatenates strings. '10' + '5' === '105', not 15. Convert each value to a number (Number(), parseInt(), or unary +) before summing.

How do I sum an array of string numbers in JavaScript?

Use reduce with a numeric initial value: amounts.reduce((acc, a) => acc + Number(a), 0). The initial value of 0 ensures the accumulator starts as a number, not a string.

How do I prevent type coercion bugs in a web API?

Validate and coerce at the boundary using a schema library - Pydantic (Python) or Zod (TypeScript). Declare the expected type (e.g. list[int]) and let the library reject or coerce bad inputs before they reach your business logic.

Can you concatenate numbers in JavaScript?

Yes, and that is the trap: the + operator concatenates if either operand is a string, so '10' + 5 becomes '105'. To add, coerce to numbers first with Number(x) or parseFloat(x).

Keep learning

Fix a React useState Stale-State BugFullstack projectFix a Blank React Dashboard (Failed Fetch)Fullstack projectFix the React Search That Won't Filter (useEffect Deps)Fullstack projectFullstack roadmapStep by step to hiredFullstack interview questionsSTAR answersAll Fullstack projectsProjects hub

Learn it by doing. Open this in a live cloud workspace, make the change yourself, and keep a record of the work you can share.

Open the workspace →