Skip to content

--uploadTimeout defaults to 0 when omitted, so every blob upload fails #162

Description

@tanmen

Summary

Since the --uploadTimeout option was added, omitting it makes msstore publish fail every time during the Azure blob upload. The option's intended default of 100 seconds is never applied when the option is absent, so 0 is used instead and every request is cancelled the instant it starts.

Root cause

MSStore.CLI/Commands/PublishCommand.cs defines the option with a CustomParser but no DefaultValueFactory:

UploadTimeoutOption = new Option<long>("--uploadTimeout", "-ut")
{
    Description = "Specifies timeout in seconds for package upload to blob storage. ...",
    CustomParser = result =>
    {
        if (result.Tokens.Count == 0)
        {
            return 100;
        }
        ...
    }
};

System.CommandLine only invokes CustomParser when the option is present on the command line. When it is omitted entirely, the value falls back to default(long), which is 0.

That 0 flows into MSStore.CLI/Services/AzureBlobManager.cs:

blobClientOptions.Retry.NetworkTimeout = TimeSpan.FromSeconds(uploadTimeout);

TimeSpan.FromSeconds(0) cancels each request immediately, the retry policy burns through its attempts, and the upload fails without a single byte transferred.

Steps to reproduce

msstore publish <package>.msix -id <storeId> --noCommit

(no --uploadTimeout)

Actual result

Uploading Bundle to Azure blob: 0%
Error while uploading the application package.

Exit code is -1. With --verbose:

fail: MSStore.CLI.ProjectConfigurators.MSIXProjectPublisher[0]
      Error while uploading the application package.
      System.AggregateException: Retry failed after 6 tries. Retry settings can be adjusted in
      ClientOptions.Retry or by configuring a custom retry policy in ClientOptions.RetryPolicy.
      (The operation was cancelled because it exceeded the configured timeout of 0:00:00.
       Network timeout can be adjusted in ClientOptions.Retry.NetworkTimeout.) ...
       ---> System.Threading.Tasks.TaskCanceledException: The operation was cancelled because it
       exceeded the configured timeout of 0:00:00. ...
          at Azure.Storage.Blobs.BlockBlobRestClient.UploadAsync(...)

Expected result

The upload proceeds using the documented default of 100 seconds.

Environment

  • CLI: v0.4.0 and v0.4.1 (both affected)
  • v0.3.9: not affected — the option does not exist there
  • Runner: windows-latest (GitHub Actions), installed via microsoft/microsoft-store-apppublisher@v1.4 with the default version: latest
  • Package: single-architecture MSIX, ~43 MB
  • Reproduced on four consecutive runs across three days

Why this is easy to misdiagnose

Two things hide the cause:

  1. Without --verbose the console shows only Error while uploading the application package. — the exception goes to logger.LogError(ex, ...) in MSStore.CLI/Helpers/IStorePackagedAPIExtensions.cs while ansiConsole.WriteLine gets a bare sentence. The failure reads as a network or service problem.
  2. The timing is consistent (~25 s), which also looks like an infrastructure issue rather than a configuration one.

It took several failed release runs before --verbose made the 0:00:00 visible.

Suggested fix

Add a DefaultValueFactory alongside the existing CustomParser, so the 100-second default applies when the option is absent as well as when it is present without a value:

UploadTimeoutOption = new Option<long>("--uploadTimeout", "-ut")
{
    DefaultValueFactory = _ => 100,
    CustomParser = result => { ... }
};

A guard in AzureBlobManager.UploadFileAsync rejecting a non-positive uploadTimeout would also turn this into an immediate, self-explanatory error rather than six silent cancellations.

Workaround

Always pass the option explicitly:

msstore publish <package>.msix -id <storeId> --noCommit --uploadTimeout 300

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions