ValueError: A Step By Step Troubleshooting Guide!

In this article, let us learn what causes ValueError and see how we can fix that to get our code up and running again!

Troubleshooting any errors will include the following steps

  • Step#1: Understand the error and its causes
  • Step#2: Figure out which of the causes actually led to the error in your particular case
  • Step#3: Apply the Fix, and test your code to confirm.
  • Step#4: Party!

Let us start by understanding ValueError and its causes!

Understanding ValueError & Its Root Cause

Instead of starting off with a definition, let’s take a look at an example!

a = "5"
b = "hi"

print(int(a))
print(int(b))

This will produce a ValueError Exception as shown below.

5
Traceback (most recent call last):
  File "/home/main.py", line 5, in <module>
    print(int(b))
ValueError: invalid literal for int() with base 10: 'hi'

The problem with our code is explained in the last line of the error text

In simple words, we cannot use the int() function to convert a “non-numerical string” object to an integer data type. This basically means the characters in the string that we give to the int( ) function must only contain numbers

In other words, the string “5” works because the contents of the string are only numbers, but the string “hi” does not work because the contents of the string are alphabets “h” and “i”

Value” in “ValueError” refers to the value of the variable

embeddedinventor.com

Hence ValueError is an exception that is raised when an incorrect value is passed to a function.

So the next time you see a ValueError, remind yourself that there is some problem with the value of a variable!

One more thing to note here is that the “data type” of the variable is correct (string), only the value stored inside the variable is wrong!

If the “data type” is wrong, say we pass in a list to a function that expects a dictionary, then a TypeError exception is raised.

The following is an excerpt from the official Python documentation:

“Raised when an operation or function receives an argument that has the right type but an inappropriate value”

python.org

Now that we learned what ValueErrors are and what causes them, fixing them is a fairly straightforward process!

There are a few tricks though, when you master these tricks they can save you lots of time and frustration in your Python journey. Let’s go ahead and see what those are next!

How to fix ValueErrors?

Here is a pro tip for you, to fix not just ValueError but any error in Python. Whenever your program crashes with an Exception, (take a deep breath and) have a look at the huge wall of error text that just got printed on your screen!

There is actually a lot of information contained in the error message, if you wish to learn the tricks then set aside 10mins of your time and read the following article!

Python: Details contained in an Exception

For visual learners out there we have also made an interesting video on that topic!

Coming back to the topic let’s see another simple example just to hammer away the point home!

print(int("hello world!"))

Here we are attempting to convert the string “hello world!” into an integer.

Since we passed a wrong value to the function (even though the data type of the variable was right), a ValueError would be raised and this will be our output:

Traceback (most recent call last):
  File "/home/main.py", line 1, in <module>
    print(int("hello world!"))
ValueError: invalid literal for int() with base 10: 'hello world!'

To understand what went wrong, we need to focus on the last line of the error message. This is where the error type and the error message are displayed:

ValueError: invalid literal for int() with base 10: 'hi'

The message is short but crisp! The message says that the argument (or ‘literal’) that is passed to our function int( ) is invalid.

Now if you’re having a hard time spotting where is the line or the code we’re supposed to change, simply refer to the error message again, as this is also usually indicated in the error message itself.

The first part of the error message does exactly that (called the stack-trace):

Traceback (most recent call last):
  File "/home/main.py", line 1, in <module>
    print(int("hello world!"))

It breaks down where it occurred exactly in the program and gives the line number on our code.

If your code is as small as this example then it might be easy to see where the error occurred by yourself, but this is rarely the case in any meaningful project, and we can imagine how useful stack-trace will be to pinpoint the error-causing statement in large and complex programs!

For visual learners:

Now we know:

  1. What the problem is (cannot pass string type data type as an argument to the function int( ))
  2. Where it occurs (line 1, print(int(“hello world!”)))

We should pass a numerical type to the function int( ), like this:

print(int("5"))

OUTPUT

5

Or we can also pass floating point numbers:

print(int(5.0))

OUTPUT:

5

So look at the value in your object and figure out what’s invalid about it and in 90% of the cases, you will intuitively know how to fix it!

For the remaining 10% of the cases, there is always Google and websites like ours!

If you are wondering if there is a way to see what values a given function accepts then you can always use the inbuilt help( ) function as shown below.

If the message there does not make proper sense, then google is your next best friend!

Next, let us see some real-life examples of where you will come across ValueError along your Python journey!

Real-life examples

Mathematical errors

ValueError is raised mostly when you are dealing with mathematical operations. For example, you mathematically cannot find the square root of a negative number:

Another place in math where you might see this is when length and areas. As you might already know, length cannot be negative, so developers usually write code like shown below to avoid bad inputs

def calc_area(length, breadth):
    if (length < 0) or (breadth < 0):
        raise ValueError
     else:
        return length * breadth

As you can see in the code above, a ValueError is raised when the length or breadth is less than 0. The internals of the examples we have seen so far has a similar theme when checking for values!

Getting input from the user

In a similar theme if you have a program where you are supposed to get input from the user, if the user enters the invalid input, a ValueError should be raised.

In this example, we will square a given number from the user. I get the inputs from the user using the built-in function input( )

The input() function returns only string value types. Hence I convert it to an integer before I square it:

def square(num):
    return num * num

num = int(input("Please enter a number: "))
print(square(num))

OUTPUT 1:

Please enter a number: 10
100

OUTPUT 2:

Please enter a number: ten
Traceback (most recent call last):
  File "/home/main.py", line 4, in <module>
    num = int(input("Please enter a number: "))
ValueError: invalid literal for int() with base 10: 'ten'

We see that if the user enters a numerical data type, everything runs smoothly:

However if the user enters a string data type, it raises an error:

The way to handle this is by using a try-block!

def square(num):
    return num * num

num = input("Please enter a number: ")

try:
    print(square(int(num)))
except ValueError:
    print("Error: You did not enter a number. Please try again.")

OUTPUT:

Please enter a number: a
Error: You did not enter a number. Please try again.

Notice how I try to convert the input value from the user in the try block, not as soon as I get the input from the user. 

This is obviously to ensure that if a statement is going to raise an error, it should be placed inside the try block for it to be handled.

And that statement here is int(num)

3. Manually raising ValueError

As we saw in our “calc_area” example, Python allows you to raise a ValueError as a developer whenever you deem it necessary.

This is not strictly confined to math problems though. Let’s look at a real-world “non-math” example where you might need to raise a ValueError!

def voting_eligibility(age, voter_id):
    if age < 18:
        raise ValueError("You are not eligible to vote.")

    if len(str(id)) != 11:
        raise ValueError("Your ID number is invalid.")
    
    print(name + " you are eligible to vote, please proceed.")


# valid voter, will not raise an error
print(voting_eligibility("Yasmin", 32, 82019375738))

# invalid voter, raises an error. Age is below required age.
print(voting_eligibility("John", 17, 94720191837))

# invalid voter, raises an error. Invalid ID.
print(voting_eligibility("Yasmin", 27, 8921))

The above is a real-life example of utilizing the ValueError. Let’s break it down:

  1. We first define a function voting_eligibility() that takes in three arguments name, age, voter_id 
  2. The function determines if the user is eligible to vote or not using two of the arguments age, voter_id
  3. If the age of the user seems to be less than 18, it is an invalid input, and hence a ValueError is raised
  4. The same is done after checking if the voter id is correct and valid or not by checking the length of the id.

As you can see, situations like this require ValueError to be raised. Hence, having familiarity with exceptions and their types just like this one will certainly help you in your Python journey!

I hope by now the ValueError has been fixed and you have tested and confirmed the fix too!

According to our troubleshooting roadmap, there is just one more pending step here, which is to celebrate our win today!!

For the next step in your Python journey I invite you to master some of the most common errors you will run into in your daily life as a Python developer. We have compiled a list of just 7 exceptions that you need to focus on if you wish to gain mastery of Exceptions in Python!

7 Most Common In-Built Exceptions in Python!

If you are a visual learner here is a YouTube video that we made on that same topic!

And with that, I will end this article.

Congratulations on making it to the end of the article, not many have the perseverance to do so!

I hope you enjoyed reading this article and found it useful!

Feel free to share it with your friends and colleagues!

If your thirst for knowledge has not been quenched yet, here are some related articles that might spark your interest!

Related Articles

TypeError: A Step By Step Troubleshooting Guide!

AttributeError: A Step By Step Troubleshooting Guide!

NameError: A Step By Step Troubleshooting Guide!

Mutable and Immutable Data Types in python explain using examples

Thanks to Namazi Jamal for his contributions to writing this article!

Photo of author
Editor
Balaji Gunasekaran
Balaji Gunasekaran is a Senior Software Engineer with a Master of Science degree in Mechatronics and a bachelor’s degree in Electrical and Electronics Engineering. He loves to write about tech and has written more than 300 articles. He has also published the book “Cracking the Embedded Software Engineering Interview”. You can follow him on LinkedIn