save_object creates local file with error content when the operation fails
If you run this:
save_object("invalid.txt", "a-valid-bucket")
As long as a-valid-bucket is a valid bucket, then the file "invalid.txt" is created in the working directory with the following contents:
<Error><Code>NoSuchKey</Code><Message>The specified key does not exist.</Message><Key>invalid.txt</Key>
I would expect that no local file is created. Does not happen when the bucket is invalid, only when the key doesn't exist.
This is, unfortunately, by design. In order to be efficient and avoid loading the entire contents into memory first, save_object instructs the HTTP engine to write the result into the specified file. It has no way of knowing whether the result from the server will be and error or the real content of the file. In HTTP terms the error is just as valid body of the response that needs to be retrieved. So the only way to avoid this would be to use an invisible file first and move it into the desired file only after the transfer is complete and the request is successful.
There are some perils in this - if a temporary directory is used, it could mean moving across file systems which is error-prone and inefficient. So I'm inclining towards something like file.path(dirname(file), paste0(".", basename(file), ".tmp.copying")) which might conflict with an existing file but hopefully unlikely.