microsoft/aspire · error · InvalidOperationException

must be a non-negative whole-second duration.

Error message

{propertyName} must be a non-negative whole-second duration.

What it means

ToInt32Seconds converts a nullable TimeSpan into whole seconds for an Azure Dev Compute (ADC) lifecycle policy field. It rejects negative values and any value with sub-second precision, throwing InvalidOperationException naming the offending property.

Solutions

  1. Round the duration to whole seconds: use TimeSpan.FromSeconds(Math.Round(value.TotalSeconds)) or TimeSpan.FromMinutes/Hours with integer amounts.
  2. Ensure the value is non-negative before assigning it to the policy property.
  3. If the value exceeds int.MaxValue seconds, use the corresponding int64-accepting property instead.

Example fix

// before
policy.IdleTimeout = TimeSpan.FromMinutes(4.5);
// after
policy.IdleTimeout = TimeSpan.FromMinutes(4);
Defensive patterns

Strategy: validation

Validate before calling

static TimeSpan WholeNonNegativeSeconds(TimeSpan t, string name)
{
    if (t < TimeSpan.Zero || t.Ticks % TimeSpan.TicksPerSecond != 0)
        throw new ArgumentException($"{name} must be a non-negative whole number of seconds.");
    return t;
}

Try / catch

try { policy.IdleTimeout = ToSeconds(cfg.Value); }
catch (InvalidOperationException ex) { /* round/floor the config duration to whole seconds and retry */ }

Prevention

When it happens

Trigger: Setting a lifecycle policy property (e.g. idle timeout, retention interval) via CreateLifecyclePolicy to a TimeSpan that is negative or contains milliseconds/ticks, such as TimeSpan.FromSeconds(30.5) or TimeSpan.FromMilliseconds(1500).

Common situations: Copying a duration from config that was specified in milliseconds, or computing a timeout with fractional seconds (e.g. minutes * 1.5).

Understand the failure class

Background: "invalid duration" / "failed to parse duration": why your timeout, interval, or TTL string is rejected and which formats each library accepts — this error's family across 32 libraries.

Related errors


AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16). Data as JSON: /api/errors/c1cd33201f5b5061. Report an issue: GitHub.

Appendix: source

Thrown at src/Aspire.Hosting.Azure.Sandboxes/AzureSandboxContainerDeployment.cs:615

            AutoDeletePolicy = hasAutoDeleteOverride ? new AzureDevComputeSandboxAutoDeletePolicy
            {
                Enabled = options!.AutoDeleteEnabled!.Value,
                DeleteIntervalInSeconds = ToInt64Seconds(options.AutoDeleteInterval, nameof(AzureSandboxOptions.AutoDeleteInterval)),
                Trigger = options.AutoDeleteTrigger?.ToString()
            } : null
        };
    }

    private static int? ToInt32Seconds(TimeSpan? value, string propertyName)
    {
        if (value is null)
        {
            return null;
        }

        if (value < TimeSpan.Zero || value.Value.Ticks % TimeSpan.TicksPerSecond != 0)
        {
            throw new InvalidOperationException($"{propertyName} must be a non-negative whole-second duration.");
        }

        var seconds = value.Value.Ticks / TimeSpan.TicksPerSecond;
        return seconds <= int.MaxValue
            ? (int)seconds
            : throw new InvalidOperationException($"{propertyName} exceeds the maximum supported ADC interval.");
    }

    private static long? ToInt64Seconds(TimeSpan? value, string propertyName)
    {
        if (value is null)
        {
            return null;
        }

        if (value < TimeSpan.Zero || value.Value.Ticks % TimeSpan.TicksPerSecond != 0)
        {
            throw new InvalidOperationException($"{propertyName} must be a non-negative whole-second duration.");

View on GitHub (pinned to 25830f84bd)