The File Upload component returns a collection of ContentDocument Ids, and the file is uploaded the moment the user picks it, before they click Next. Set Related Record ID on the component if you already know which record the file belongs to. If you do not, you are creating ContentDocumentLink records yourself afterwards, and you are also dealing with the files left behind by users who abandoned the flow.
What the component gives you
Drag File Upload onto a screen and the settings that matter are the label, Allowed File Types, Allow Multiple Files, and Related Record ID. The output is a Text collection of ContentDocument Ids, referenced as {!Upload_Component.contentDocumentIds}.
Note what that is not. It is not the file, not the ContentVersion, and not the file name. To get the name, size or type you query ContentVersion:
ContentDocumentId In {!Upload_Component.contentDocumentIds}
IsLatest Equals True
That gives you Title, FileExtension, ContentSize and VersionData references for each uploaded file.
The upload happens before Next
This is the behaviour that shapes every design decision here. The file is committed to the platform as soon as the user selects it. Clicking Previous does not remove it. Closing the browser does not remove it. A validation failure later on the screen does not remove it.
Two things follow. First, you cannot treat the file as provisional, so any “are you sure” step has to come before the upload screen rather than after it. Second, orphaned files accumulate. If Related Record ID was not set, those files are owned by the uploading user and linked to nothing, invisible in every list view and quietly consuming file storage.
Linking the file to the right record
If the record exists when the screen renders, set Related Record ID on the component and the platform creates the link for you. This is by far the better path. Use it whenever the flow is launched from a record page and receives recordId.
When the record is created later in the flow, you link afterwards. Loop the contentDocumentIds collection, build a collection of ContentDocumentLink records, and create them in one element after the loop:
- ContentDocumentId: the loop item.
- LinkedEntityId: the Id of the record you just created.
- ShareType:
Vfor viewer,Cfor collaborator,Ifor inferred.Vis the usual choice. - Visibility:
AllUsersfor internal sharing, orInternalUserswhere community access should be excluded.
Build the collection inside the loop and do a single Create Records after it. One DML, not one per file.
Requiring a file
Do not rely on the component to enforce it. Put a Decision after the screen testing {!Upload_Component.contentDocumentIds} Is Null True, and route the failing path back to the same screen with an error variable driving a Display Text component at the top. Same pattern as any other cross-component validation, and it is the one that keeps working when the requirement grows.
Guest users
Uploads from an Experience Cloud site are a different problem, and most of the difficulty is sharing rather than the component.
Guest user security means a guest cannot generally see or link records the way an internal user can. The approach that works is to set Related Record ID on the component so the platform performs the linking, rather than creating ContentDocumentLink rows yourself in guest context. Where you must create the link, the flow needs to run in system context, and you need to be deliberate about that choice rather than stumbling into it.
The org also has to permit it. Check that guest access to files is enabled for the site, that the guest profile has the object permissions the rest of the flow needs, and that the site’s guest user sharing rules cover the record you are attaching to. Test as an actual guest in a private browser window, not as an internal user with the site preview, because the two behave differently in exactly the ways that matter here.
Frequently asked
Can I read the file’s contents in the flow? Not usefully. VersionData is base64 and flow has no decoding functions. Anything that inspects the contents is invocable Apex.
Why does the file appear on the wrong record? Related Record ID was set to a variable that was empty or held the wrong Id. A file linked to nothing behaves the same way as a file linked to the wrong thing: it is not where you looked.
Is there a file size limit? Yes, the standard platform file size limits apply, and large files upload slowly inside a screen. Say so in the help text rather than letting users discover it.
