{"record":{"id":"d50d8348d26aef2d","repo":"boto/boto3","slug":"filename-must-be-a-string-or-a-path-like-object","errorCode":null,"errorMessage":"Filename must be a string or a path-like object","messagePattern":"Filename must be a string or a path-like object","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"boto3/s3/transfer.py","lineNumber":445,"sourceCode":"        else:\n            self._manager = create_transfer_manager(client, config, osutil)\n\n    def upload_file(\n        self, filename, bucket, key, callback=None, extra_args=None\n    ):\n        \"\"\"Upload a file to an S3 object.\n\n        Variants have also been injected into S3 client, Bucket and Object.\n        You don't have to use S3Transfer.upload_file() directly.\n\n        .. seealso::\n            :py:meth:`S3.Client.upload_file`\n            :py:meth:`S3.Client.upload_fileobj`\n        \"\"\"\n        if isinstance(filename, PathLike):\n            filename = fspath(filename)\n        if not isinstance(filename, str):\n            raise ValueError('Filename must be a string or a path-like object')\n\n        subscribers = self._get_subscribers(callback)\n        future = self._manager.upload(\n            filename, bucket, key, extra_args, subscribers\n        )\n        try:\n            future.result()\n        # If a client error was raised, add the backwards compatibility layer\n        # that raises a S3UploadFailedError. These specific errors were only\n        # ever thrown for upload_parts but now can be thrown for any related\n        # client error.\n        except ClientError as e:\n            raise S3UploadFailedError(\n                f\"Failed to upload {filename} to {bucket}/{key}: {e}\"\n            )\n\n    def download_file(\n        self, bucket, key, filename, extra_args=None, callback=None","sourceCodeStart":427,"sourceCodeEnd":463,"githubUrl":"https://github.com/boto/boto3/blob/6e10b029c1326a437932a8b24f38af69fd986e15/boto3/s3/transfer.py#L427-L463","documentation":"Raised by `S3Transfer.upload_file` after a `PathLike`-to-string conversion attempt: the `filename` argument must ultimately be a `str`. boto3 accepts `os.PathLike` objects (it calls `os.fspath` on them) but rejects anything else (None, int, bytes, an already-open file object). To stream from an open file handle, use `upload_fileobj` instead.","triggerScenarios":"Calling `client.upload_file(None, bucket, key)`, `upload_file(b'data', ...)`, `upload_file(open(path), ...)` (passing a file object), or `upload_file(123, ...)`.","commonSituations":"Passing an open file handle to `upload_file` (meant for `upload_fileobj`); a filename variable that resolved to None due to a missing user input or a failed `tempfile` call; building the path with bytes on a system where `os.fspath` does not yield `str`.","solutions":["Pass a real filesystem path as a string or pathlib.Path: `client.upload_file('/tmp/f', bucket, key)`.","If you have an open file object, switch to `client.upload_fileobj(fileobj, bucket, key)`.","Guard against None: `if filename: client.upload_file(filename, ...)`.","Coerce pathlib Paths explicitly if unsure: `str(pathlib.Path(...))`."],"exampleFix":"# before\nwith open('/tmp/f', 'rb') as f:\n    client.upload_file(f, 'bucket', 'key')  # f is a file object, not a path\n\n# after\nclient.upload_file('/tmp/f', 'bucket', 'key')\n# or, for an open handle:\nwith open('/tmp/f', 'rb') as f:\n    client.upload_fileobj(f, 'bucket', 'key')","handlingStrategy":"type-guard","validationCode":"from pathlib import Path\nimport os\n\ndef upload_path(p):\n    if isinstance(p, os.PathLike):\n        p = os.fspath(p)\n    if not isinstance(p, str):\n        raise TypeError('filename must be a str or os.PathLike')\n    client.upload_file(p, bucket, key)","typeGuard":"import os\ndef is_path_or_str(p) -> bool:\n    return isinstance(p, (str, os.PathLike))","tryCatchPattern":"try:\n    client.upload_file(filename, bucket, key)\nexcept ValueError as e:\n    if 'Filename must be a string' in str(e):\n        client.upload_file(str(filename), bucket, key)  # or use upload_fileobj","preventionTips":["Use upload_file only for filesystem paths; use upload_fileobj for open handles.","Build paths with pathlib.Path to stay PathLike-safe.","Reject None filenames at your input boundary."],"tags":["s3","upload","type-validation","argument-validation"],"backgroundTag":null,"analyzedSha":"6e10b029c1326a437932a8b24f38af69fd986e15","analyzedAt":"2026-08-11T20:52:47.213Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}