windmill-labs/windmill · error · Exception

Could not write file to S3

Error message

Could not write file to S3

What it means

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__.

Source

Thrown at python-client/wmill/wmill/client.py:1019

            query_params["content_type"] = content_type
        if content_disposition is not None:
            query_params["content_disposition"] = content_disposition

        try:
            # need a vanilla client b/c content-type is not application/json here
            response = httpx.post(
                f"{self.base_url}/w/{self.workspace}/job_helpers/upload_s3_file",
                headers={
                    "Authorization": f"Bearer {self.token}",
                    "Content-Type": "application/octet-stream",
                },
                params=query_params,
                content=content_payload,
                verify=self.verify,
                timeout=None,
            ).json()
        except Exception as e:
            raise Exception("Could not write file to S3") from e
        return S3Object(s3=response["file_key"], storage=s3object.get("storage") if s3object else None)

    def delete_s3_object(
        self,
        s3object: S3Object | str,
        s3_resource_path: str | None = None,
    ) -> None:
        """
        Permanently delete a file from the workspace S3 bucket.

        '''python
        from wmill import S3Object

        s3_obj = S3Object(s3="/path/to/my_file.txt")
        client.delete_s3_object(s3_obj)
        '''
        """
        s3object = parse_s3_object(s3object)

View on GitHub (pinned to e474e8803c)

Solutions

  1. Inspect the chained cause: catch the error and log e.__cause__
  2. Verify S3 storage is configured in instance settings
  3. Check workspace token validity (re-run inside Windmill or refresh the token)
  4. Confirm the s3 resource path / s3object file_key is correct
  5. Check backend reachability for httpx connection errors

Example fix

// before
wm.write_s3_file(s3obj, data)
// after
try:
    wm.write_s3_file(s3obj, data)
except Exception as e:
    logger.error(f"S3 write failed: {e.__cause__}")
    raise
Defensive patterns

Strategy: try-catch

Validate before calling

import os
assert os.environ.get("WM_TOKEN") or wm.get_client().token, "No workspace token configured"

Try / catch

try:
    wm.write_s3_file(s3obj, data)
except Exception as e:
    cause = e.__cause__
    logger.error(f"S3 write failed: {cause}")
    raise RuntimeError(f"S3 write failed: {cause}") from cause

Prevention

When it happens

Trigger: 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.

Common situations: Self-hosted instance without S3 storage configured, invalid token after a workspace change, oversized payload, typo'd s3 resource path, backend temporarily down.

Understand the failure class

Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.

Related errors


AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03). Data as JSON: /api/errors/cf47b29e59e786a6. Report an issue: GitHub.