s3cmd crashes with ‘expected str instance, bytes found’
Upgrading my Linux system to Fedora 39 brought in Python 3.12, which turns out to be the culprit with s3cmd 2.3.0 being unable to sync – or even list – files with my Amazon S3-compatible cloud storage buckets. It kept throwing “An unexpected error has occurred” and a stacktrace that ended with:
File "/usr/lib/python3.12/site-packages/S3/BaseUtils.py", line 257, in stripNameSpace
xml = RE_XML_NAMESPACE.sub("\\1\\2", xml, 1)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: sequence item 1: expected str instance, bytes found
Python 3.12 is stricter about whether the input and substitution parameters in its regular expression functions are the same type. Here the input (xml
) is raw bytes, and the substitution pattern ("\\1\\2"
) is a plain string.
It’s fixable with literally a one-letter change to S3/BaseUtils.py. Find the line highlighted above, and change it to:
xml = RE_XML_NAMESPACE.sub(b"\\1\\2", xml, 1)
Or you can run the current master branch of s3cmd, or wait for the next release, because they’ve already fixed it. Or use a different AWS/S3 client.
This affects any system running Python 3.12. The original bug report was on macOS Sonoma. Depending on your OS, distribution, how you’ve installed Python, and how you’ve installed s3cmd, the file you need to edit will be in a different place. Fortunately the error message will tell you where to look!