{"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":"validation","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/c7b4afac237b976d48395d7523eaf7cec3a450b3/boto3/s3/transfer.py#L427-L463","documentation":"Raised by S3Transfer.upload_file after it converts pathlib path-likes to strings and confirms the result is a str. upload_file takes a filesystem path (not a file object) and streams it to S3; if the value is neither a str nor an os.PathLike it cannot be opened, so boto3 rejects it with this ValueError before attempting any transfer.","triggerScenarios":"Calling upload_file(filename, ...) where filename is None, an int, an already-open file handle, a bytes object, or any non-str/non-PathLike value. Commonly: passing an open file where upload_fileobj was intended.","commonSituations":"Mixing up upload_file (path) vs upload_fileobj (file handle); passing None because the path variable was never assigned; passing a Path subclass that does not implement __fspath__.","solutions":["Pass the filesystem path as a string or pathlib.Path: s3.upload_file('/tmp/data.bin', bucket, key).","If you have an open file handle, switch to s3.upload_fileobj(f, bucket, key).","If the path comes from another call, assert it is set and is a str/Path before calling: isinstance(filename, (str, pathlib.Path))."],"exampleFix":"// before\nwith open('/tmp/data.bin', 'rb') as f:\n    s3.upload_file(f, 'bkt', 'key')  # wrong: file handle, not path\n\n// after\ns3.upload_file('/tmp/data.bin', 'bkt', 'key')\n# or, for a file handle:\nwith open('/tmp/data.bin', 'rb') as f:\n    s3.upload_fileobj(f, 'bkt', 'key')","handlingStrategy":"type-guard","validationCode":"import os, pathlib\nif not isinstance(filename, (str, os.PathLike)):\n    raise TypeError('filename must be a str or os.PathLike')\ns3.upload_file(filename, bucket, key)","typeGuard":"def is_upload_path(filename) -> bool:\n    import os\n    return isinstance(filename, (str, os.PathLike))","tryCatchPattern":"try:\n    s3.upload_file(filename, bucket, key)\nexcept ValueError as e:\n    if 'string or a path-like' in str(e):\n        s3.upload_fileobj(filename, bucket, key)  # filename was actually a file handle","preventionTips":["Use upload_file for paths and upload_fileobj for open handles.","Assert isinstance(filename, (str, pathlib.Path)) before calling.","Ensure the path variable is assigned (not None) before the call."],"tags":["boto3","s3","upload","validation","api-misuse"],"analyzedSha":"c7b4afac237b976d48395d7523eaf7cec3a450b3","analyzedAt":"2026-08-04T20:35:51.598Z","schemaVersion":2}