Skip to content

How to Resolve Python Error "ValueError: invalid literal for int() with base 10"

Learn how to fix the Python ValueError when converting strings to integers, including handling non-digit characters, decimal points, and empty strings with code examples.

The ValueError: invalid literal for int() with base 10: '...' is a frequent Python error encountered when using the int() function to convert a string to an integer. It signifies that the string provided to int() does not represent a valid whole number in base 10 (our standard decimal system) and therefore cannot be directly converted.

This guide explains the common reasons for this error – like non-digit characters, decimal points, or empty strings – and provides solutions for handling or cleaning the input string before conversion.

Understanding the Error: What int() Expects

The built-in int() function, when given a string argument, attempts to parse that string as an integer according to the specified base (which defaults to base 10). For base 10, a valid string must:

  • Contain only digit characters (0 through 9).
  • Optionally have a leading sign (+ or -).
  • Not contain decimal points (.) or other non-digit characters (letters, symbols, spaces within the number).
  • Not be empty or contain only whitespace after stripping.

The ValueError occurs when the input string violates these rules. The part of the error message after the colon (: '...') shows the specific invalid literal (the string) that int() could not parse.

Cause 1: String Contains Non-Digit Characters

This includes letters, symbols, spaces within the digits, or other characters that aren't 0-9 (or a leading sign).

Error Scenario

string_with_letters = "12a3"
string_with_symbols = "1,000" # Comma is not a digit
string_with_spaces = "1 2 3"

try:
    num = int(string_with_letters)
except ValueError as e:
    print(e)

try:
    num = int(string_with_symbols)
except ValueError as e:
    print(e)

try:
    num = int(string_with_spaces)
except ValueError as e:
    print(e)

Solution: Validate Input / Handle Errors (try...except)

Especially when dealing with user input or external data, you cannot guarantee the string will be valid. The most robust approach is to wrap the int() call in a try...except ValueError block.

user_input = input("Enter a whole number: ") # User might enter 'abc'

try:
    number = int(user_input)
    print(f"You entered the integer: {number}")
except ValueError:
    print(f"Invalid input: '{user_input}' is not a valid whole number.")
    number = 0 # Example fallback

Solution: Extract Digits Before Conversion (If Appropriate)

If you know the string might contain non-digits but you only want to convert the digits present, you can filter them out first. Use this cautiously, as it might not be appropriate for all inputs (e.g., "1a2b" becomes 12).

import re

mixed_string = "ID: 456-ABC"

digits_only = "".join(filter(str.isdigit, mixed_string))
print(f"Digits extracted: '{digits_only}'") # Output: '456'
if digits_only: # Check if any digits were found
    number = int(digits_only)
    print(f"Converted number: {number}") # Output: 456
else:
    print("No digits found in string.")

match = re.search(r'\d+', mixed_string) # Find first sequence of digits
if match:
    number_re = int(match.group(0))
    print(f"First number found (regex): {number_re}") # Output: 456
else:
    print("No number sequence found.")

Cause 2: String Represents a Float (Contains Decimal Point)

The int() function cannot directly parse strings containing a decimal point (.), even if the fractional part is zero (like "5.0").

Error Scenario

float_string = "123.45"
zero_decimal_string = "5.0"

try:
    num = int(float_string)
except ValueError as e:
    print(e)

try:
    num = int(zero_decimal_string)
except ValueError as e:
    print(e)

Solution: Convert to float() First, then int()

The standard way to handle this is to first convert the string to a float using float(), and then convert that float to an int. Converting a float to an int truncates (removes) the decimal part.

float_string = "123.45"
zero_decimal_string = "5.0"

try:
    num_float = float(float_string) # Converts to 123.45
    num_int = int(num_float)        # Truncates to 123
    print(f"'{float_string}' -> float: {num_float} -> int: {num_int}")

    num_float_zero = float(zero_decimal_string) # Converts to 5.0
    num_int_zero = int(num_float_zero)          # Truncates to 5
    print(f"'{zero_decimal_string}' -> float: {num_float_zero} -> int: {num_int_zero}")

except ValueError:
     print("String is not a valid float.")

Handling Rounding (Optional)

If you need standard rounding instead of truncation when converting from a float string:

import math

float_string = "123.78"
float_string_low = "123.12"

num_int_rounded = int(round(float(float_string)))
print(f"'{float_string}' rounded to int: {num_int_rounded}")    # Output: 124

num_int_ceil = int(math.ceil(float(float_string)))
print(f"'{float_string}' ceiling to int: {num_int_ceil}")       # Output: 124

num_int_floor = int(math.floor(float(float_string_low)))
print(f"'{float_string_low}' floor to int: {num_int_floor}")    # Output: 123

Cause 3: Empty or Whitespace-Only String

Passing an empty string ("") or a string containing only whitespace (" ") to int() will also cause a ValueError.

Error Scenario

empty_str = ""
space_str = "   "

try:
    num = int(empty_str)
except ValueError as e:
    print(e)

try:
    num = int(space_str)
except ValueError as e:
    print(e)

Solution: Check and Provide Default (e.g., or '0')

Use string stripping and the or operator to provide a default value (like '0') if the string is empty after stripping whitespace.

empty_str = ""
space_str = "   "

num_empty = int(empty_str.strip() or '0')
print(f"Result for empty string: {num_empty}") # Output: Result for empty string: 0

num_space = int(space_str.strip() or '0')
print(f"Result for space string: {num_space}") # Output: Result for space string: 0

valid_str = " 123 "
num_valid = int(valid_str.strip() or '0')
print(f"Result for valid string: {num_valid}") # Output: Result for valid string: 123
  • my_str.strip(): Removes leading/trailing whitespace.
  • ... or '0': If my_str.strip() results in an empty string (which is falsy), the expression evaluates to '0'. Otherwise, it evaluates to the stripped string.

Solution: Use if Check Before Conversion

Explicitly check if the stripped string is non-empty.

maybe_empty = "  "
number = 0 # Default

stripped = maybe_empty.strip()
if stripped: # Check if string is non-empty after stripping
    try:
        number = int(stripped)
        print("Conversion successful.")
    except ValueError:
        print(f"Stripped string '{stripped}' is not a valid integer.")
else:
    print("String is empty or contains only whitespace.") # This is executed

print(f"Final number: {number}")

Best Practice: Use try...except ValueError

Because you often cannot guarantee the format of strings coming from external sources (user input, files, APIs), the most robust and Pythonic way to handle potential conversion errors is to always wrap int() calls in a try...except ValueError block when dealing with strings.

def safe_string_to_int(input_str, default=0):
  """Safely converts a string to an int, returning default on failure."""
  try:
    return int(input_str.strip())
  except (ValueError, TypeError, AttributeError): # Catch errors if input is None, not string, or invalid format
    print(f"Warning: Could not convert '{input_str}' to int. Returning default.")
    return default

print(safe_string_to_int(" 123 "))  # Output: 123
print(safe_string_to_int("45a"))    # Output: Warning... Returning default. -> 0
print(safe_string_to_int("  "))     # Output: Warning... Returning default. -> 0
print(safe_string_to_int(None))     # Output: Warning... Returning default. -> 0
print(safe_string_to_int("5.6"))    # Output: Warning... Returning default. -> 0

Output:

123
Warning: Could not convert '45a' to int. Returning default.
0
Warning: Could not convert '  ' to int. Returning default.
0
Warning: Could not convert 'None' to int. Returning default.
0
Warning: Could not convert '5.6' to int. Returning default.
0

Conclusion

The ValueError: invalid literal for int() with base 10 occurs when you pass a string to int() that doesn't strictly represent a whole number in base 10.

Key solutions include:

  1. Handle Invalid Characters: Use try...except ValueError to catch errors from strings containing non-digits (letters, symbols, internal spaces). Optionally pre-process strings to remove/extract digits if appropriate.
  2. Handle Float Strings: Convert float-like strings (e.g., "123.45") to float() first, then to int() (which truncates). Use round(), math.ceil(), or math.floor() after float() if specific rounding is needed.
  3. Handle Empty/Whitespace Strings: Use .strip() combined with the or '0' fallback or an if check before calling int().

Using try...except ValueError is the most reliable way to handle potentially invalid string inputs before integer conversion.

Navigation