Skip to content

azure-ai-ml: upload_directory silently swallows upload errors when show_progress=False #48269

Description

@achauhan-scc

Summary

azure.ai.ml._utils._asset_utils.upload_directory silently swallows worker upload failures when show_progress=False, so a directory upload can fail without raising, leaving a partial/incomplete upload in remote storage while callers proceed as if it succeeded.

Package

  • Name: azure-ai-ml
  • File: sdk/ml/azure-ai-ml/azure/ai/ml/_utils/_asset_utils.py
  • Function: upload_directory

Root cause

Files are uploaded via a ThreadPoolExecutor. Exceptions raised inside a worker (upload_file) are captured on the Future and only re-raised when future.result() is called. That call currently lives only inside the if show_progress: branch:

with ThreadPoolExecutor(max_workers=num_cores) as ex:
    futures_dict = { ex.submit(upload_file, ...): (src, dest) for ... }
    if show_progress:
        with tqdm(...) as pbar:
            for future in as_completed(futures_dict):
                future.result()  # only reached when show_progress=True
                pbar.update(...)
    # when show_progress=False, .result() is never called -> exceptions swallowed

When show_progress=False, no one calls future.result(). The executor's shutdown(wait=True) waits for the threads to finish, but the stored exceptions are never observed, so upload_directory returns normally as if the upload succeeded.

Expected behavior

Upload errors should propagate regardless of the show_progress value.

Actual behavior

With show_progress=False, upload errors are silently ignored and the function returns None (apparent success).

Fix

Observe all futures (call future.result()) even when progress is disabled. Fixed in PR #48242.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions