{"id":"cb87edc34bdcb3a1","repo":"boto/boto3","slug":"fileobj-must-implement-write","errorCode":null,"errorMessage":"Fileobj must implement write","messagePattern":"Fileobj must implement write","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"boto3/s3/inject.py","lineNumber":841,"sourceCode":"    :type Fileobj: a file-like object\n    :param Fileobj: A file-like object to download into. At a minimum, it must\n        implement the `write` method and must accept bytes.\n\n    :type ExtraArgs: dict\n    :param ExtraArgs: Extra arguments that may be passed to the\n        client operation. For allowed download arguments see\n        :py:attr:`boto3.s3.transfer.S3Transfer.ALLOWED_DOWNLOAD_ARGS`.\n\n    :type Callback: function\n    :param Callback: A method which takes a number of bytes transferred to\n        be periodically called during the download.\n\n    :type Config: boto3.s3.transfer.TransferConfig\n    :param Config: The transfer configuration to be used when performing the\n        download.\n    \"\"\"\n    if not hasattr(Fileobj, 'write'):\n        raise ValueError('Fileobj must implement write')\n\n    subscribers = None\n    if Callback is not None:\n        subscribers = [ProgressCallbackInvoker(Callback)]\n\n    config = Config\n    if config is None:\n        config = TransferConfig()\n\n    new_config = python_copy.copy(config)\n    disable_threading_if_append_mode(new_config, Fileobj)\n\n    with create_transfer_manager(self, new_config) as manager:\n        future = manager.download(\n            bucket=Bucket,\n            key=Key,\n            fileobj=Fileobj,\n            extra_args=ExtraArgs,","sourceCodeStart":823,"sourceCodeEnd":859,"githubUrl":"https://github.com/boto/boto3/blob/c7b4afac237b976d48395d7523eaf7cec3a450b3/boto3/s3/inject.py#L823-L859","documentation":"Raised by the injected download_fileobj() helper when the destination Fileobj argument lacks a 'write' attribute. download_fileobj writes the downloaded bytes into a file-like object via the managed transfer manager, so the target must implement write() accepting bytes. Anything that cannot receive binary writes is rejected up front with this ValueError.","triggerScenarios":"Calling s3.download_fileobj(Bucket, Key, Fileobj) / bucket.download_fileobj(Key, Fileobj) where Fileobj is a filename string (use download_file instead), a file opened in read mode ('r'/'rb'), a bytes object, a StringIO, None, or any object without a write method.","commonSituations":"Confusing download_file (takes a filename) with download_fileobj (takes an open writable file); opening the target file with open(path, 'r') instead of 'wb'; passing a string path; reusing a read handle as the download target.","solutions":["Pass an open writable binary handle: with open(path, 'wb') as f: s3.download_fileobj(bucket, key, f).","If you want to download straight to a path, use s3.download_file(bucket, key, filename) instead.","For in-memory downloads, target io.BytesIO() and call getvalue() afterwards.","Confirm the handle is not opened in read or text mode."],"exampleFix":"// before\nwith open('out.txt', 'r') as f:\n    s3.download_fileobj('mybucket', 'key', f)  # wrong: not writable\n\n// after\nwith open('out.txt', 'wb') as f:\n    s3.download_fileobj('mybucket', 'key', f)","handlingStrategy":"type-guard","validationCode":"if not hasattr(fileobj, 'write'):\n    raise TypeError('download_fileobj requires a writable file-like object')\ns3.download_fileobj(bucket, key, fileobj)","typeGuard":"def is_writable_fileobj(obj) -> bool:\n    return hasattr(obj, 'write') and callable(getattr(obj, 'write'))","tryCatchPattern":"try:\n    s3.download_fileobj(bucket, key, fileobj)\nexcept ValueError as e:\n    if 'must implement write' in str(e):\n        with open(path, 'wb') as f:\n            s3.download_fileobj(bucket, key, f)","preventionTips":["Always open download targets with open(path, 'wb').","Use download_file(path, ...) for a filename and download_fileobj(f, ...) for a handle.","Never reuse a read-mode handle as a download destination."],"tags":["boto3","s3","download","fileobj","validation"],"analyzedSha":"c7b4afac237b976d48395d7523eaf7cec3a450b3","analyzedAt":"2026-08-04T20:35:51.598Z","schemaVersion":2}