Passing an incorrect argument to a function is one of the most common sources of runtime errors in Python. When the type, value, or number of arguments doesn’t match what the function expects, you’ll typically see a TypeError, ValueError, or unexpected behavior — and in production code, these can crash your program or produce silent bugs. In 2026, robust functions use type hints, input validation, and proper exception handling to detect and respond to bad arguments gracefully.
Here’s a complete, practical guide to understanding what happens when you pass wrong arguments, how to catch and handle these issues, and modern best practices to make your code resilient and user-friendly.
Start with the classic case: a function expecting a number gets a string instead. Python tries to perform the operation — and fails with a TypeError.
def double(num: float) -> float:
"""Double a number."""
return num * 2
# Correct call
print(double(5)) # 10.0
# Incorrect argument type
try:
print(double("5")) # TypeError: can't multiply sequence by non-int of type 'str'
except TypeError as e:
print(f"Type error: {e}")
Even worse: silent bugs when the wrong type “works” in an unexpected way. Strings support multiplication by integers — so "hello" * 3 gives "hellohellohello", which might hide the real problem until much later.
def repeat_text(text: str, times: int = 3) -> str:
return text * times
# Looks fine, but wrong type
print(repeat_text(5)) # TypeError: can't multiply sequence by non-int of type 'int'
# Oops — intended to repeat a string, but passed a number
Real-world pattern: user input or file parsing often delivers strings — always convert and validate.
def calculate_area(radius_str: str) -> float:
"""Calculate circle area from radius string input."""
try:
radius = float(radius_str) # Convert string ? float
if radius < 0:
raise ValueError("Radius cannot be negative")
return 3.14159 * radius ** 2
except ValueError as e:
print(f"Invalid radius: {e}")
return 0.0
except TypeError:
print("Radius must be a number or numeric string")
return 0.0
print(calculate_area("7.5")) # 176.7144375
print(calculate_area("abc")) # Invalid radius: could not convert string to float: 'abc'
print(calculate_area(-3)) # Invalid radius: Radius cannot be negative
Best practices make argument errors detectable and graceful. Use type hints — they document expectations and help tools like mypy/pylance catch issues early. Validate inputs early — check types, ranges, and formats with isinstance(), if guards, or assert. Raise meaningful exceptions — ValueError for bad values, TypeError for wrong types. Wrap risky conversions in try/except — especially float(), int(), or user input. Log errors in production — use logging instead of print to track bad calls. Prefer raise over returning None or magic values — callers can handle exceptions explicitly. Modern tip: use pydantic or attrs for data validation — they automatically check types, ranges, and constraints with nice error messages. Another powerful option: structural pattern matching (Python 3.10+) in except blocks for fine-grained handling.
Passing incorrect arguments is inevitable — especially with user input, APIs, or files. In 2026, don’t let it crash your program. Use type hints to document, validation to catch, exceptions to communicate, and logging to track. Handle errors thoughtfully, and your functions become robust, debuggable, and production-ready.
Next time you accept input or call a function — assume it might be wrong. Validate, convert safely, and handle exceptions. That’s the difference between brittle code and reliable systems.