{"record":{"id":"cb87edc34bdcb3a1","repo":"boto/boto3","slug":"fileobj-must-implement-write","errorCode":null,"errorMessage":"Fileobj must implement write","messagePattern":"Fileobj must implement write","errorType":"exception","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/6e10b029c1326a437932a8b24f38af69fd986e15/boto3/s3/inject.py#L823-L859","documentation":"Raised by the injected `download_fileobj` helper before a download starts. boto3 writes incoming bytes by calling `write()` on the supplied `Fileobj`, so the target must be a writable binary stream. Passing bytes, a string, a path, or a read-only object is rejected up front. Use `download_file` when you want to write directly to a path.","triggerScenarios":"Calling `client.download_fileobj(Bucket=..., Key=..., Fileobj=<bytes|str|path|None>)` or `bucket.download_fileobj(key, <read-only-or-non-file-object>)`. Common when a variable intended to be an open file is actually a path string or None.","commonSituations":"Confusing `download_file` (takes a path) with `download_fileobj` (takes an open writable stream); passing a path string; passing a BytesIO opened/used incorrectly; forgetting to open the destination; passing a file opened in `'rb'` (read-only) mode.","solutions":["If you want a file on disk by path, use `client.download_file(bucket, key, filename)` instead of `download_fileobj`.","Pass an open writable binary handle: `with open(path, 'wb') as f: client.download_fileobj(bucket, key, f)`.","For in-memory capture, use `from io import BytesIO; buf = BytesIO(); client.download_fileobj(bucket, key, buf)`.","Ensure the destination handle is opened in write/append binary mode (`'wb'`/`'ab'`), not read mode."],"exampleFix":"# before\nclient.download_fileobj('mybucket', 'key.txt', '/tmp/key.txt')  # path string has no .write\n\n# after\nwith open('/tmp/key.txt', 'wb') as f:\n    client.download_fileobj('mybucket', 'key.txt', f)","handlingStrategy":"validation","validationCode":"def download_target(obj):\n    assert hasattr(obj, 'write'), 'download_fileobj needs a writable file-like object'\n    return obj\n\nwith open(path, 'wb') as f:\n    client.download_fileobj(bucket, key, download_target(f))","typeGuard":"def is_writable_fileobj(o) -> bool:\n    return hasattr(o, 'write') and callable(o.write)","tryCatchPattern":"try:\n    client.download_fileobj(bucket, key, target)\nexcept ValueError as e:\n    if 'must implement write' in str(e):\n        with open(target, 'wb') as f:\n            client.download_fileobj(bucket, key, f)  # target was a path","preventionTips":["Open destination files in write-binary ('wb').","Use download_file for paths and download_fileobj for open streams.","Never pass a path string or None as the Fileobj argument."],"tags":["s3","download","fileobj","type-validation"],"backgroundTag":null,"analyzedSha":"6e10b029c1326a437932a8b24f38af69fd986e15","analyzedAt":"2026-08-11T20:52:47.213Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}