BugHunt

Type errors: when a number is secretly a string

Totals that concatenate, sorts that put 10 before 9, comparisons that refuse to run.

13 free challenges6 Python7 JavaScript

What is type error?

A value is not the type the code assumes. Python usually raises immediately; JavaScript usually converts silently and gives a wrong answer, which is worse because nothing tells you anything went wrong.

Why it happens

Data crossing a boundary loses its type. Form fields, JSON, query strings and CSV files all arrive as text. JSON object keys are always strings even when they look like numbers. JavaScript's + means addition or concatenation depending on its operands, and its default sort compares elements as strings.

How to recognise it

  • A total is a string of digits stuck together rather than a sum.
  • Sorting puts 10 before 9 — string ordering, not numeric.
  • KeyError on a key you can see in the printed dict (it is "1", not 1).
  • In Python 3, / always returns a float, so it can never be an index.

Errors and symptoms this causes

  • TypeError: unsupported operand type(s)
  • TypeError: '>' not supported between instances of 'str' and 'int'
  • TypeError: list indices must be integers or slices, not float
  • sort puts 10 before 9
  • numbers concatenating instead of adding

How to fix it

Convert once, at the boundary where data enters, rather than scattering int() and Number() through your logic. Use === over == in JavaScript so type mismatches fail loudly. When a value surprises you, print its type before you print its value.

Practise type errors

Working code with one bug in it. Find it, fix it in the browser, and see the explanation. No account needed.

javascriptEasy
Cart total comes out as gibberish

calculateTotal(items) should add up the price of every item and return the total, e.g. two items at 10 and 20 gives 30.

Type error

pythonEasy
Float division makes an invalid index

middle_item(items) should return the middle element, so middle_item([1, 2, 3]) returns 2.

Type error

pythonEasy
Average always comes back as a whole number

average(nums) should return the mean of a list of numbers, including any fractional part.

Type error

pythonEasy
Price formatting crashes on numbers

format_price(amount) should return the amount formatted as a price string, e.g. format_price(5) -> "$5".

Type error

javascriptHard
typeof reports null as an object

describeType(value) should name the type of a value, returning "null" for null and "object" for real objects.

Type error

javascriptHard
Identical objects counted as different

countUnique(records) should count distinct records by their contents, so two records with the same fields count once.

Type error

pythonHard
JSON keys are strings, but the ids are numbers

total_for_ids(counts, ids) totals the counts for the given ids. counts comes from a JSON payload, e.g. {"1": 10, "2": 20}, and ids are integers.

Type error

javascriptMedium
Counting votes concatenates instead of adding

countVotes(entries) should add up the votes field of every entry and return the numeric total.

Type error

pythonMedium
Numbers arriving as text never compare properly

count_above(values, threshold) counts how many values exceed the threshold. The values arrive as strings from a form, so count_above(["1", "5", "10"], 3) should return 2.

Type error

javascriptMedium
Sorting numbers puts 10 before 9

sortNumbers(nums) should return the numbers sorted from smallest to largest.

Type error

javascriptMedium
parseInt quietly throws away the decimals

sumPrices(prices) should total a list of price strings, so sumPrices(["1.5", "2.5"]) returns 4.

Type error

pythonMedium
Highest score picked alphabetically

highest(values) should return the largest number from a list of numeric strings, so highest(["9", "10", "2"]) returns "10".

Type error

javascriptMedium
Loose equality counts empty strings as zero

countZeros(values) should count how many entries are the number zero, so countZeros([0, "", false, 0]) returns 2.

Type error

Other bug patterns