{"record":{"id":"cf47b29e59e786a6","repo":"windmill-labs/windmill","slug":"could-not-write-file-to-s3","errorCode":null,"errorMessage":"Could not write file to S3","messagePattern":"Could not write file to S3","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"python-client/wmill/wmill/client.py","lineNumber":1019,"sourceCode":"            query_params[\"content_type\"] = content_type\n        if content_disposition is not None:\n            query_params[\"content_disposition\"] = content_disposition\n\n        try:\n            # need a vanilla client b/c content-type is not application/json here\n            response = httpx.post(\n                f\"{self.base_url}/w/{self.workspace}/job_helpers/upload_s3_file\",\n                headers={\n                    \"Authorization\": f\"Bearer {self.token}\",\n                    \"Content-Type\": \"application/octet-stream\",\n                },\n                params=query_params,\n                content=content_payload,\n                verify=self.verify,\n                timeout=None,\n            ).json()\n        except Exception as e:\n            raise Exception(\"Could not write file to S3\") from e\n        return S3Object(s3=response[\"file_key\"], storage=s3object.get(\"storage\") if s3object else None)\n\n    def delete_s3_object(\n        self,\n        s3object: S3Object | str,\n        s3_resource_path: str | None = None,\n    ) -> None:\n        \"\"\"\n        Permanently delete a file from the workspace S3 bucket.\n\n        '''python\n        from wmill import S3Object\n\n        s3_obj = S3Object(s3=\"/path/to/my_file.txt\")\n        client.delete_s3_object(s3_obj)\n        '''\n        \"\"\"\n        s3object = parse_s3_object(s3object)","sourceCodeStart":1001,"sourceCodeEnd":1037,"githubUrl":"https://github.com/windmill-labs/windmill/blob/e474e8803ce2ff5c2df09a58dab51d45f5c922ca/python-client/wmill/wmill/client.py#L1001-L1037","documentation":"The HTTP request to the Windmill backend's S3 write endpoint failed with any exception from the httpx client. The original exception is chained, so the underlying cause (auth failure, network error, backend 4xx/5xx) is available in __cause__.","triggerScenarios":"write_s3_file when the backend errors or the connection fails: expired/invalid workspace token, S3 storage not configured on the instance, missing/invalid s3_resource_path or s3object file_key, network outage, backend 500.","commonSituations":"Self-hosted instance without S3 storage configured, invalid token after a workspace change, oversized payload, typo'd s3 resource path, backend temporarily down.","solutions":["Inspect the chained cause: catch the error and log e.__cause__","Verify S3 storage is configured in instance settings","Check workspace token validity (re-run inside Windmill or refresh the token)","Confirm the s3 resource path / s3object file_key is correct","Check backend reachability for httpx connection errors"],"exampleFix":"// before\nwm.write_s3_file(s3obj, data)\n// after\ntry:\n    wm.write_s3_file(s3obj, data)\nexcept Exception as e:\n    logger.error(f\"S3 write failed: {e.__cause__}\")\n    raise","handlingStrategy":"try-catch","validationCode":"import os\nassert os.environ.get(\"WM_TOKEN\") or wm.get_client().token, \"No workspace token configured\"","typeGuard":null,"tryCatchPattern":"try:\n    wm.write_s3_file(s3obj, data)\nexcept Exception as e:\n    cause = e.__cause__\n    logger.error(f\"S3 write failed: {cause}\")\n    raise RuntimeError(f\"S3 write failed: {cause}\") from cause","preventionTips":["Verify S3 storage is configured in instance settings before using S3 APIs","Keep workspace tokens fresh and scoped to the right workspace","Log e.__cause__ (the httpx error) for diagnosis","Retry on transient httpx.TransportError"],"tags":["network","s3","http","windmill-api"],"backgroundTag":"http-request-failed","analyzedSha":"e474e8803ce2ff5c2df09a58dab51d45f5c922ca","analyzedAt":"2026-09-03T12:38:19.024Z","contentChangedAt":"2026-09-03T12:38:19.024Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}