microsoft/aspire · error · InvalidOperationException

ADC request ' ' returned an incomplete response.

Error message

ADC request '{method} {path}' returned an incomplete response.

What it means

AzureDevComputeClient validates that a deserialized ADC (Azure Dev Compute) create-response contains the required fields: the result must be non-null, and disk images must have a non-empty Id and Status.State while sandboxes must have a non-empty Id. If any of these invariants are missing from an otherwise successful response, the client treats the response as unusable and throws InvalidOperationException naming the HTTP method and path.

Solutions

  1. Log the raw response body for the failing '{method} {path}' request and compare it with the AzureDevComputeDiskImage/AzureDevComputeSandbox DTOs to find the missing field.
  2. Update to the latest Aspire.Hosting.Azure.Sandboxes package where the DTOs match the current ADC API contract.
  3. Check the ADC API version/endpoint being used; pin to an API version known to return complete payloads.
  4. If triggered by propagation delay, poll the resource (GET) until Id/Status.State are populated instead of relying on the create response.
  5. Inspect any proxy, gateway, or custom HttpClient handler in the pipeline that could alter or truncate response JSON.

Example fix

// before: assuming create response is complete
var sandbox = await client.SendCreateAsync(request, ct);
Use(sandbox.Id);
// after: tolerate incomplete create response by fetching the resource
var sandbox = await client.SendCreateAsync(request, ct);
sandbox ??= await client.GetAsync(name, ct);
if (string.IsNullOrWhiteSpace(sandbox?.Id)) { throw ... }
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-flight: probe the ADC resource before relying on the create response
var sandbox = await client.GetAsync(name, ct);
if (sandbox is null || string.IsNullOrWhiteSpace(sandbox.Id))
{
    throw new InvalidOperationException("ADC sandbox not yet available; poll until Id/Status.State are populated.");
}

Type guard

static bool IsComplete(AzureDevComputeResult? r) => r switch
{
    null => false,
    AzureDevComputeDiskImage d => !string.IsNullOrWhiteSpace(d.Id) && d.Status?.State is { Length: > 0 },
    AzureDevComputeSandbox s => !string.IsNullOrWhiteSpace(s.Id),
    _ => false
};

Try / catch

try
{
    var result = await client.SendCreateAsync(request, ct);
    if (!IsComplete(result)) { /* retry with GET */ }
}
catch (InvalidOperationException ex) when (ex.Message.Contains("returned an incomplete response"))
{
    // log method/path from message, poll the resource, then retry
}

Prevention

When it happens

Trigger: Calling the ADC API via SendCreateAsync when the service returns HTTP success (2xx) but the deserialized body is null, a AzureDevComputeDiskImage without Id or Status/Status.State, or a AzureDevComputeSandbox without an Id.

Common situations: ADC service bugs or API version drift returning partial payloads; proxies/gateways stripping response fields; a mismatch between the client's DTO shape and the actual service contract; the sandbox/disk image being deleted or not yet initialized between creation and the response.

Related errors


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

Appendix: source

Thrown at src/Aspire.Hosting.Azure.Sandboxes/Internal/Adc/AzureDevComputeClient.cs:278

                    // Reconcile by deployment labels rather than retrying the non-idempotent request.
                    throw new AzureDevComputeCreateException(ex, responseMayHaveBeenLost: (int)response.StatusCode >= 500);
                }
                catch (OperationCanceledException ex)
                {
                    throw new AzureDevComputeCreateException(ex, responseMayHaveBeenLost: (int)response.StatusCode >= 500);
                }
            }

            try
            {
                var result = await response.Content.ReadFromJsonAsync<T>(s_jsonSerializerOptions, cancellationToken).ConfigureAwait(false);
                if (result is null ||
                    (result is AzureDevComputeDiskImage diskImage && string.IsNullOrWhiteSpace(diskImage.Id)) ||
                    (result is AzureDevComputeDiskImage { Status: null }) ||
                    (result is AzureDevComputeDiskImage { Status.State: var state } && string.IsNullOrWhiteSpace(state)) ||
                    (result is AzureDevComputeSandbox sandbox && string.IsNullOrWhiteSpace(sandbox.Id)))
                {
                    throw new InvalidOperationException($"ADC request '{method} {path}' returned an incomplete response.");
                }

                return result;
            }
            catch (Exception ex) when (ex is JsonException or InvalidOperationException or HttpRequestException or IOException or NotSupportedException)
            {
                // The service may have committed the create before returning an empty or malformed payload.
                throw new AzureDevComputeCreateException(ex, responseMayHaveBeenLost: true);
            }
            catch (OperationCanceledException ex)
            {
                throw new AzureDevComputeCreateException(ex, responseMayHaveBeenLost: true);
            }
        }
    }

    private async Task<HttpResponseMessage> SendWithRetryAsync(
        AzureDevComputeResourceScope scope,

View on GitHub (pinned to 25830f84bd)