microsoft/aspire · error · InvalidOperationException

An input name is required when uploading a file.

Error message

An input name is required when uploading a file.

What it means

UploadFileAsync requires request.InputName to identify which interaction input the file belongs to; it throws InvalidOperationException when InputName is null or empty. The fileUploadStore.CreateEntry call keys the stored file by interaction id and input name, so the name is mandatory.

Solutions

  1. Set InputName to the exact input property name declared by the file-upload interaction (e.g., "CertificateFile").
  2. Read the expected input name from the interaction definition instead of hardcoding an empty value.
  3. Check that refactoring the interaction's inputs did not rename the field used in the upload request.

Example fix

// before
await rpc.UploadFileAsync(new UploadFileRequest { FileName = f, Data = bytes, InteractionId = id, InputName = "" });
// after
await rpc.UploadFileAsync(new UploadFileRequest { FileName = f, Data = bytes, InteractionId = id, InputName = "CertificateFile" });
Defensive patterns

Strategy: validation

Validate before calling

if (string.IsNullOrEmpty(request.InputName))
{
    throw new InvalidOperationException("Set InputName to the interaction input property the file belongs to.");
}

Type guard

static bool HasInputName(UploadFileRequest r) => !string.IsNullOrEmpty(r.InputName);

Try / catch

try
{
    await rpc.UploadFileAsync(request, cancellationToken);
}
catch (InvalidOperationException ex) when (ex.Message.Contains("input name is required"))
{
    // set InputName from the interaction definition and retry
}

Prevention

When it happens

Trigger: Calling UploadFileAsync with a request whose InputName is null or "" — e.g., constructing the request without knowing the target input property name of the file-upload interaction.

Common situations: Generic upload helpers that set FileName and Data but skip InputName; a rename of the interaction's input property not propagated to the upload call; hand-built requests in scripts.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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

Appendix: source

Thrown at src/Aspire.Hosting/Backchannel/AppHostRpcTarget.cs:267

    /// Registers a local file in the upload store by copying it to a managed temp location.
    /// Returns the file ID that can be used to reference the file in interaction responses.
    /// </summary>
    public async Task<UploadFileResponse> UploadFileAsync(UploadFileRequest request, CancellationToken cancellationToken = default)
    {
        var maxUploadSize = FileUploadHelpers.GetMaxFileUploadSize(configuration);

        if (request.Data.Length > maxUploadSize)
        {
            throw new InvalidOperationException($"File '{request.FileName}' exceeds the maximum upload size of {maxUploadSize} bytes.");
        }

        if (request.InteractionId <= 0)
        {
            throw new InvalidOperationException("An interaction ID is required when uploading a file.");
        }
        if (string.IsNullOrEmpty(request.InputName))
        {
            throw new InvalidOperationException("An input name is required when uploading a file.");
        }

        var (fileId, filePath) = fileUploadStore.CreateEntry(request.FileName, request.InteractionId, request.InputName);

        try
        {
            var destStream = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None, bufferSize: 81920, useAsync: true);
            await using (destStream.ConfigureAwait(false))
            {
                await destStream.WriteAsync(request.Data, cancellationToken).ConfigureAwait(false);
            }
        }
        catch
        {
            fileUploadStore.RemoveEntry(request.InteractionId, fileId);
            throw;
        }

View on GitHub (pinned to 25830f84bd)