Repository navigation
Retrying internal errors in files_upload_v2 #1730
Description
Activity
- addedenhancementM-T: A feature request for new functionalityM-T: A feature request for new functionalityand removed
on Aug 21, 2025 Hi @tjstum thanks for bringing this up 💯
Adding some sort of retry handler for
file_update_failedon a request tofiles.completeUploadExternalseems like a logical feature, especially since this all happens within thefiles_upload_v2method. In order to implement this correctly, we should add a way to pass specific retry handlers per api_method to reduce bloating.Until then, here is an implementation of a
FileUploadFailRetryHandlerthat can be used as a workaround until we figure out the proper way to implement all this.import os import logging from pathlib import Path from typing import Optional from slack_sdk import WebClient from slack_sdk.http_retry import RetryHandler, RetryState, HttpRequest, HttpResponse, default_retry_handlers from slack_sdk.http_retry.handler import default_interval_calculator logging.basicConfig(level=logging.INFO) FILE_PATH = Path("./README.md") FILE_NAME = "README.md" class FileUploadFailRetryHandler(RetryHandler): """Custom Retry handler for file_update_failed errors during file uploads.""" def __init__( self, max_retry_count: int = 1, interval_calculator=default_interval_calculator, api_methods=["files.completeUploadExternal"], ): super().__init__(max_retry_count, interval_calculator) self.api_methods = set(api_methods) def _can_retry( self, *, state: RetryState, request: HttpRequest, response: Optional[HttpResponse] = None, error: Optional[Exception] = None, ) -> bool: if error is not None or response is None: return False request_url = request.url if not any(api_method in request_url for api_method in self.api_methods): return False body = response.body if body.get("ok", False) is False: if body.get("error") == "file_update_failed": return True return False def main(): retry_handlers = default_retry_handlers() retry_handlers.append(FileUploadFailRetryHandler()) client = WebClient(token=os.environ.get("SLACK_BOT_TOKEN"), retry_handlers=retry_handlers) with open(FILE_PATH, "rb") as file: file_content = file.read() result = client.files_upload_v2( channel="C123", # You can change this to your target channel content=file_content, filename=FILE_NAME, title="Bolt for Python file upload", initial_comment="Here's the file for our project", ) client.logger.info(f"File uploaded: {result['file']['id']}") if __name__ == "__main__": main()
Thanks. We'll give this a shot for now. We see this error infrequently (5 times in August), but it always confuses our users.
I'll stay tuned for how you want to implement this within
files_upload_v2!👋 It looks like this issue has been open for 30 days with no activity. We'll mark this as stale for now, and wait 10 days for an update or for further comment before closing this issue out. If you think this issue needs to be prioritized, please comment to get the thread going again! Maintainers also review issues marked as stale on a regular basis and comment or adjust status if the issue needs to be reprioritized.
Hi there,
We occasionally see transient errors from the Slack API in calls to
files.completeUploadExternalthat are done within the SDK's implementation offiles_upload_v2. The error we see most frequently error we encounter isfile_update_failed, which has more or less no useful explanation on the API docs. Support has also not been very helpful in understanding the nature of these issues: they just said there is a temporary server error, and we should retry the call tocompleteUploadExternalCan the Python SDK implement that retr? It doesn't seem like the caller of
files_upload_v2(i.e. our code) could, since that would redo the entire upload. The caller also doesn't have enough information to retry thefiles.completeUploadExternalcall, since the ID is lost when the SDK throws an exception.I suppose a workaround is to install a custom
RetryHandleron theWebClient. But like in #1715, shouldn't that just be part of the SDK?Category