From 7b58fb062d33b34f990f009464083bb56d8c2fb0 Mon Sep 17 00:00:00 2001 From: nileshpatil6 Date: Wed, 3 Jun 2026 22:26:35 +0530 Subject: [PATCH] fix(processing): close temp file handle before deletion on Windows FrameworkProcessor._package_code called os.unlink(tmp.name) inside the NamedTemporaryFile with block, while the file handle was still open. On Windows this raises PermissionError (WinError 32) because files cannot be deleted while any handle is open. On Linux/macOS the pattern works but leaks a file handle via the bare open() call. Move os.unlink outside the with block so the handle is closed first, and use a proper with-statement for the S3 upload read. Fixes #5873 Signed-off-by: nileshpatil6 --- .../src/sagemaker/core/processing.py | 26 ++++++++++++------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/sagemaker-core/src/sagemaker/core/processing.py b/sagemaker-core/src/sagemaker/core/processing.py index 62493719dc..0b5521a809 100644 --- a/sagemaker-core/src/sagemaker/core/processing.py +++ b/sagemaker-core/src/sagemaker/core/processing.py @@ -1157,7 +1157,8 @@ def _package_code( # Create tar.gz with source_dir contents with tempfile.NamedTemporaryFile(suffix=".tar.gz", delete=False) as tmp: - with tarfile.open(tmp.name, "w:gz") as tar: + tmp_path = tmp.name + with tarfile.open(tmp_path, "w:gz") as tar: # Add all files from source_dir to the root of the tar for item in os.listdir(source_dir): item_path = os.path.join(source_dir, item) @@ -1172,15 +1173,22 @@ def _package_code( ) # Upload the tar file directly to S3 - s3.S3Uploader.upload_string_as_file_body( - body=open(tmp.name, "rb").read(), - desired_s3_uri=s3_uri, - kms_key=kms_key, - sagemaker_session=self.sagemaker_session, - ) + with open(tmp_path, "rb") as f: + s3.S3Uploader.upload_string_as_file_body( + body=f.read(), + desired_s3_uri=s3_uri, + kms_key=kms_key, + sagemaker_session=self.sagemaker_session, + ) - os.unlink(tmp.name) - return s3_uri + # Delete outside the with block so the file handle is closed first. + # On Windows, a file cannot be deleted while any handle remains open + # (PermissionError WinError 32); on Linux/macOS this is not an issue. + try: + os.unlink(tmp_path) + except OSError: + pass + return s3_uri @_telemetry_emitter(feature=Feature.PROCESSING, func_name="FrameworkProcessor.run") @runnable_by_pipeline