{"record":{"id":"d5c7fbd148eceefc","repo":"microsoft/aspire","slug":"an-input-name-is-required-when-uploading-a-file","errorCode":null,"errorMessage":"An input name is required when uploading a file.","messagePattern":"An input name is required when uploading a file\\.","errorType":"validation","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Aspire.Hosting/Backchannel/AppHostRpcTarget.cs","lineNumber":267,"sourceCode":"    /// Registers a local file in the upload store by copying it to a managed temp location.\n    /// Returns the file ID that can be used to reference the file in interaction responses.\n    /// </summary>\n    public async Task<UploadFileResponse> UploadFileAsync(UploadFileRequest request, CancellationToken cancellationToken = default)\n    {\n        var maxUploadSize = FileUploadHelpers.GetMaxFileUploadSize(configuration);\n\n        if (request.Data.Length > maxUploadSize)\n        {\n            throw new InvalidOperationException($\"File '{request.FileName}' exceeds the maximum upload size of {maxUploadSize} bytes.\");\n        }\n\n        if (request.InteractionId <= 0)\n        {\n            throw new InvalidOperationException(\"An interaction ID is required when uploading a file.\");\n        }\n        if (string.IsNullOrEmpty(request.InputName))\n        {\n            throw new InvalidOperationException(\"An input name is required when uploading a file.\");\n        }\n\n        var (fileId, filePath) = fileUploadStore.CreateEntry(request.FileName, request.InteractionId, request.InputName);\n\n        try\n        {\n            var destStream = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None, bufferSize: 81920, useAsync: true);\n            await using (destStream.ConfigureAwait(false))\n            {\n                await destStream.WriteAsync(request.Data, cancellationToken).ConfigureAwait(false);\n            }\n        }\n        catch\n        {\n            fileUploadStore.RemoveEntry(request.InteractionId, fileId);\n            throw;\n        }\n","sourceCodeStart":249,"sourceCodeEnd":285,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Hosting/Backchannel/AppHostRpcTarget.cs#L249-L285","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Set InputName to the exact input property name declared by the file-upload interaction (e.g., \"CertificateFile\").","Read the expected input name from the interaction definition instead of hardcoding an empty value.","Check that refactoring the interaction's inputs did not rename the field used in the upload request."],"exampleFix":"// before\nawait rpc.UploadFileAsync(new UploadFileRequest { FileName = f, Data = bytes, InteractionId = id, InputName = \"\" });\n// after\nawait rpc.UploadFileAsync(new UploadFileRequest { FileName = f, Data = bytes, InteractionId = id, InputName = \"CertificateFile\" });","handlingStrategy":"validation","validationCode":"if (string.IsNullOrEmpty(request.InputName))\n{\n    throw new InvalidOperationException(\"Set InputName to the interaction input property the file belongs to.\");\n}","typeGuard":"static bool HasInputName(UploadFileRequest r) => !string.IsNullOrEmpty(r.InputName);","tryCatchPattern":"try\n{\n    await rpc.UploadFileAsync(request, cancellationToken);\n}\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"input name is required\"))\n{\n    // set InputName from the interaction definition and retry\n}","preventionTips":["Reference the interaction input property via nameof so renames propagate at compile time.","Make upload helper methods take the input name as a required parameter."],"tags":["rpc","interactions","missing-argument"],"backgroundTag":"missing-required-argument","analyzedSha":"25830f84bd145686607ad00c057b3f84e2e51d43","analyzedAt":"2026-09-16T11:10:06.193Z","contentChangedAt":"2026-09-16T11:10:06.193Z","schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}