When user attaches files on Notes and Attachments related list from Salesforce UI then files gets attached to Files and Notes and Attachments related list. But when I do it from vf page/apex then it just attaches it to Notes and Attachment related list.

Attachment myAttachment  = new Attachment();
myAttachment.Body = fileBody;
myAttachment.Name = fileName;
myAttachment.ParentId = aLead.id;
insert myAttachment;

Files uploaded to the Attachments related list on records are uploaded as Salesforce Files, not as attachment

enter image description here

2 Answers 2


Like the option says it attaches files only when its uploaded from related list(Only from the standard related list UI). From apex you're supposed to insert a contentDocument, which is a salesforce file but what you're attaching is just an attachment. Salesforce doesn't automatically convert attachment into a file. You need to insert a file explicitly!

ContentDocument : Represents a document that has been uploaded to a library in Salesforce CRM Content or Salesforce Files. This object is available in versions 17.0 and later for Salesforce CRM Content. This object is available in API version 21.0 and later for Salesforce Files.

For more info please refer Difference between Attachments and ContentDocument along with How can I create a Chatter File via Apex?


I have a similar situation where I have a ton of web forms that create cases and if the user is in Classic, they are auto-forwarded to that case's Classic File Attachment page (the one where it's step 1: select file, step 2: attach file, step 3: click done). I couldn't figure out how to link directly to the new file upload button, so instead I set up a trigger on Attachment, with a Before and After, to move attachments over to files.

trigger AttachmentSaver on Attachment (after insert, before insert) {
    if (Trigger.isInsert) {
        if (Trigger.isBefore) {

            for (Attachment att : Trigger.new) {

                ContentVersion cv = new ContentVersion();
                cv.PathOnClient = att.Name;
                cv.Title = att.Name;
                cv.Description = att.Name;
                cv.VersionData = att.body;
                cv.FirstPublishLocationId = att.ParentId;
                insert cv;

                att.description = att.Name + '-relocatedToFiles';


        if (Trigger.isAfter) {
            delete [select id from Attachment WHERE id in :Trigger.new AND description like '%-relocatedToFiles'];

It's not exactly the most elegant since it involves creating two attachments and immediately deletes one of them, but this ensures that anything we have that link directly to the classic File Attachment page will ultimately create ContentVersion files. If users are using Lightning, they are taken to a page where they can drag and drop files, so once everyone is migrated (hopefully soon), this code can be removed.

I know this is an older post, but hopefully this helps someone. Or, if it is a terrible idea and someone knows of a better way, that would be good to know.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .