{"record":{"id":"01df505ee37907f5","repo":"dotnet/aspnetcore","slug":"there-is-no-file-with-id-fileid-the-file-list","errorCode":null,"errorMessage":"There is no file with ID ${fileId}. The file list may have changed. See https://aka.ms/aspnet/blazor-input-file-multiple-selections.","messagePattern":"There is no file with ID (.+?)\\. The file list may have changed\\. See https://aka\\.ms/aspnet/blazor-input-file-multiple-selections\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/Components/Web.JS/src/InputFile.ts","lineNumber":117,"sourceCode":"    contentType: format,\n    blob: resizedImageBlob ? resizedImageBlob : originalFile.blob,\n  };\n\n  elem._blazorFilesById[result.id] = result;\n\n  return result;\n}\n\nasync function readFileData(elem: InputElement, fileId: number): Promise<Blob> {\n  const file = getFileById(elem, fileId);\n  return file.blob;\n}\n\nexport function getFileById(elem: InputElement, fileId: number): BrowserFile {\n  const file = elem._blazorFilesById[fileId];\n\n  if (!file) {\n    throw new Error(`There is no file with ID ${fileId}. The file list may have changed. See https://aka.ms/aspnet/blazor-input-file-multiple-selections.`);\n  }\n\n  return file;\n}\n","sourceCodeStart":99,"sourceCodeEnd":122,"githubUrl":"https://github.com/dotnet/aspnetcore/blob/294cab2f9b2e03af6b953820c7ab497c3c8b7ad9/src/Components/Web.JS/src/InputFile.ts#L99-L122","documentation":"Thrown by getFileById when the requested file ID is not present in the InputFile element's internal _blazorFilesById map. Blazor's InputFile JS interop tracks chosen files by a monotonically-increasing ID; that map is rebuilt from scratch on every 'change' event and cleared on 'cancel', so any stale file ID held by .NET becomes invalid the moment the user picks files again or cancels the dialog.","triggerScenarios":"Calling IBrowserFile.OpenReadStream / ReadAsStreamAsync, or InputFile's toImageFile/readFileData JS interop, with a IBrowserFile reference obtained from a previous InputFile change callback after the user has since reopened the picker and selected new files (or pressed Cancel). Also triggered when multiple-file selection is disabled and code assumes the ID stays valid across selections.","commonSituations":"Storing IBrowserFile instances in component state and reusing them after another OnChange; wiring an upload button that triggers a second change before processing the first; migrating code from single-file to multiple-file selection without invalidating cached file references.","solutions":["Process files synchronously inside the OnChange handler (or kick off the stream read immediately) before the user can select again, rather than holding IBrowserFile references long-term.","Copy the bytes to your own buffer/stream during OnChange and never reference the IBrowserFile afterward.","If you must defer, capture only the data you need into component state in OnChange and treat subsequent OnChange as replacing the whole set.","Avoid calling OpenReadStream on a file whose change event has been superseded; guard with a flag tracking whether the list changed."],"exampleFix":"// before: hold the file, use later\nprivate IBrowserFile _file; // set in OnChange, used in a button click\nawait _file.OpenReadStream().CopyToAsync(ms); // throws if user picked again\n\n// after: read immediately in OnChange\nasync Task OnChange(InputFileChangeEventArgs e)\n{\n    await using var stream = e.File.OpenReadStream(maxAllowedSize);\n    await stream.CopyToAsync(_ms); // done with IBrowserFile right away\n}","handlingStrategy":"validation","validationCode":"// Before calling IBrowserFile.OpenReadStream, ensure the file is still current.\n// Track a token that changes on each InputFile OnChange:\nprivate int _fileSetToken;\nasync Task OnChange(InputFileChangeEventArgs e)\n{\n    _fileSetToken++;\n    var token = _fileSetToken;\n    // capture bytes now; do not retain e.File past this handler\n}\n// In any deferred action, compare token == _fileSetToken before using a file.","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Process IBrowserFile bytes inside OnChange rather than caching the IBrowserFile.","Treat each OnChange as invalidating all previous file references.","Disable the input while an async upload is in flight to prevent re-selection."],"tags":["blazor","inputfile","interop","state"],"analyzedSha":"294cab2f9b2e03af6b953820c7ab497c3c8b7ad9","analyzedAt":"2026-08-06T20:08:02.189Z","schemaVersion":2},"datasetVersion":"2026-08-06T23:17:07.152Z"}