Last updated: Apr 11, 2024
Reading time·4 min
The Python "OSError [Errno 22] invalid argument" is most often caused when you
have an invalid character in your filename when calling open()
, e.g. a colon
:
or a question mark ?
.
To solve the error, make sure the specified path doesn't contain any invalid characters.
The specified path has to either be an absolute or a relative path.
For example, if you are on Windows, you can specify an absolute path as follows.
# Windows absolute path file_path = r'C:\Users\bobbyhadz\example.txt' with open(file_path, 'r', encoding='utf-8') as my_file: print(my_file.readlines())
Notice that we prefixed the string with an r
to mark it as a raw string.
Prefixing the string with an r
enables us to treat backslashes as literal
characters and not as escape characters.
Alternatively, you can escape each backslash \
with another backslash.
# Windows absolute path file_path = r'C:\\Users\\bobbyhadz\\example.txt' with open(file_path, 'r', encoding='utf-8') as my_file: print(my_file.readlines())
You can also replace the backslashes with forward slashes when separating the path components.
# Windows absolute path file_path = r'C:/Users/bobbyhadz/example.txt' with open(file_path, 'r', encoding='utf-8') as my_file: print(my_file.readlines())
However, make sure you don't have single backslash characters in the path
without prefixing the string with r
.
Single backslash characters are used as escape characters which would invalidate your path.
If you are on macOS or Linux, your absolute path might look something like this:
# macOS and Linux absolute path file_path = '/home/bobbyhadz/Desktop/example.txt' with open(file_path, 'r', encoding='utf-8') as my_file: print(my_file.readlines())
You can also use a relative path to the file you're trying to open.
# Relative path file_path = 'example.txt' with open(file_path, 'r', encoding='utf-8') as my_file: print(my_file.readlines())
The code sample assumes that you have an example.txt
file in the same
directory as your main.py
script.
Suppose you have the following folder structure.
my-project/ └── main.py └── text-files/ └── example.txt
You would use the following path to open the text-files/example.txt
file.
# Relative path file_path = 'text-files/example.txt' with open(file_path, 'r', encoding='utf-8') as my_file: print(my_file.readlines())
You can also use the following path to achieve the same result.
file_path = './text-files/example.txt'
Suppose you have the following folder structure.
my-project/ └── src/ └── main.py └── example.txt
You would use the following path to open the example.txt
file from
src/main.py
.
# Relative path file_path = '../example.txt' with open(file_path, 'r', encoding='utf-8') as my_file: print(my_file.readlines())
The ../
prefix enables us to go one directory up.
If you need to go two directories up, you'd use the prefix twice ../../
.
Another common cause of the "OSError [Errno 22] invalid argument" error is
when your path contains invalid characters, e.g. a question mark ?
, an angle
bracket <
or a hash #
symbol.
If you are on macOS or Linux, make sure your file path doesn't contain colons
:
either.
Try to rename your file path to one that doesn't contain any special characters.
You can use ASCII letters (a-zA-Z), digits (0-9), hyphens -
and underscores
_
.
You might also get the error when trying to use a timestamp as the name of the file.
from datetime import datetime # 2023-06-24 16:03:57.084126 my_file = open(str(datetime.now()), "w", encoding='utf-8') my_file.write('bobbyhadz.com') my_file.close()
Notice that the timestamp contains colons :
.
You have to use a filename that doesn't contain any special characters.
If your filename is stored in a variable, try to remove all special characters from the string.
import re filename = '2023-06-24 16:03:57.084126' filename = re.sub(r'[^\w_. -]', '_', filename) print(filename) # 👉️ 2023-06-24 16_03_57.084126
The code sample uses the
re.sub() method
to replace all non-letter, non-digit, non-underscore, non-period, non-space and
non-underscore characters with an underscore _
.
The colons from the original string are replaced with underscores.
You can also decide to remove the special characters by replacing them with empty strings.
import re filename = '2023-06-24 16:03:57.084126' filename = re.sub(r'[^\w_. -]', '', filename) print(filename) # 👉️ 2023-06-24 160357.084126
The code sample removes all special characters from the filename.
Alternatively, you can use the str.replace() method.
filename = '2023-06-24 16:03:57.084126' filename = filename.replace(':', '_').replace('.', '_') print(filename) # 👉️ 2023-06-24 16_03_57_084126
The str.replace()
method returns a copy of the string with all occurrences of
a substring replaced by the provided replacement.
The method takes the following parameters:
Name | Description |
---|---|
old | The substring we want to replace in the string |
new | The replacement for each occurrence of old |
count | Only the first count occurrences are replaced (optional) |
You can chain the method as many times as necessary because it returns the new string (with the matches replaced).
You can learn more about the related topics by checking out the following tutorials: