{"record":{"id":"addf393e113e2540","repo":"microsoft/aspire","slug":"interaction-interactionid-is-not-accepting-file-uploads-for","errorCode":null,"errorMessage":"Interaction '{interactionId}' is not accepting file uploads for input '{inputName}'.","messagePattern":"Interaction '(.+?)' is not accepting file uploads for input '(.+?)'\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Aspire.Hosting/Dashboard/InteractionFileUploadStore.cs","lineNumber":59,"sourceCode":"    /// Creates a new temp file path and returns the file ID and path.\n    /// </summary>\n    public (string FileId, string FilePath) CreateEntry(string originalFileName, int interactionId, string inputName)\n    {\n        if (!_interactions.TryGetValue(interactionId, out var interaction))\n        {\n            throw new InvalidOperationException($\"Interaction '{interactionId}' is not accepting file uploads.\");\n        }\n\n        lock (interaction)\n        {\n            if (interaction.State != FileInteractionState.InProgress)\n            {\n                throw new InvalidOperationException($\"Interaction '{interactionId}' is not accepting file uploads.\");\n            }\n\n            if (!interaction.FileInputLimits.TryGetValue(inputName, out var maxFileCount))\n            {\n                throw new InvalidOperationException($\"Interaction '{interactionId}' is not accepting file uploads for input '{inputName}'.\");\n            }\n\n            // Each client submits one file selection per input during an interaction. Multi-file selections upload\n            // their files sequentially as part of that single selection, so every upload counts toward this limit.\n            // Count uploads in progress as reserved slots so concurrent requests cannot exceed the input's limit.\n            var fileCount = interaction.Files.Values.Count(entry => string.Equals(entry.InputName, inputName, StringComparisons.InteractionInputName));\n            if (fileCount >= maxFileCount)\n            {\n                var fileLabel = maxFileCount == 1 ? \"file\" : \"files\";\n                throw new InvalidOperationException($\"File input '{inputName}' accepts at most {maxFileCount} {fileLabel}.\");\n            }\n\n            // Keep only the leaf name as metadata. The client-supplied name is never used for the\n            // on-disk path because filename rules vary by platform and some names have special semantics.\n            var lastSep = originalFileName.AsSpan().LastIndexOfAny('/', '\\\\');\n            var safeName = lastSep >= 0 ? originalFileName[(lastSep + 1)..] : originalFileName;\n\n            var tempFile = _tempFileSystem.CreateTempFile();","sourceCodeStart":41,"sourceCodeEnd":77,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Hosting/Dashboard/InteractionFileUploadStore.cs#L41-L77","documentation":"The store keeps a per-input limit table (FileInputLimits) describing which file inputs an interaction accepts. If the supplied inputName is not registered for the interaction, uploads for that input are rejected. This distinguishes 'interaction closed' from 'input not recognized'.","triggerScenarios":"CreateEntry called with an inputName that does not match any key in the interaction's FileInputLimits dictionary (typo'd name, input removed before upload, or upload sent for an input belonging to a different interaction).","commonSituations":"Frontend sending a form field name that changed after the interaction was created; client code uploading files for inputs declared with different casing or names; uploading to a completed interaction that had a differently-named input.","solutions":["Verify the inputName exactly matches the name declared when the interaction's file input was added","Re-fetch the interaction definition so the client uses the current input names","Catch InvalidOperationException and report which inputs are accepted (from FileInputLimits) to aid debugging"],"exampleFix":"// before\nawait store.CreateEntry(interactionId, \"attachment\", file.Name, stream);\n// after\nvar inputName = FileUploadInputs.Attachment; // must match the name registered in FileInputLimits\nawait store.CreateEntry(interactionId, inputName, file.Name, stream);","handlingStrategy":"validation","validationCode":"if (!interaction.FileInputLimits.ContainsKey(inputName))\n{\n    throw new ArgumentException($\"Input '{inputName}' is not registered for interaction '{interactionId}'.\");\n}","typeGuard":"bool IsKnownInput(InteractionFileUploadStore.Interaction i, string inputName) =>\n    i.FileInputLimits.ContainsKey(inputName);","tryCatchPattern":"try\n{\n    await store.CreateEntry(interactionId, inputName, fileName, stream);\n}\ncatch (InvalidOperationException ex) when (ex.Message.Contains($\"for input '{inputName}'\"))\n{\n    // Report the mismatch; list accepted inputs from interaction.FileInputLimits.\n}","preventionTips":["Use constants/shared names for file inputs instead of string literals","Verify input names against FileInputLimits before uploading","Keep client form field names and interaction input names in sync","Re-read the interaction definition after any schema change"],"tags":["dashboard","file-upload","unknown-input"],"backgroundTag":"invalid-argument-value","analyzedSha":"25830f84bd145686607ad00c057b3f84e2e51d43","analyzedAt":"2026-09-16T11:10:06.193Z","contentChangedAt":"2026-09-16T11:10:06.193Z","schemaVersion":2},"datasetVersion":"2026-09-21T09:17:21.228Z"}