I have a custom object named 'comments' with which i made a 'action'.it is having a trigger handler class

 public void onAfterInsert(Comments__c[] newComments){

            for(Comments__c comRec:newComments){
                FeedItem post = new FeedItem();
                post.ParentId = comRec.case__c; 
                post.IsRichText = true;
                post.body =  comRec.Case_Comments__c;  
                        insert post;
                catch(Exception e){

the 'case comments' field is a rich text but when i add a image to it in case feed it is creating a comment but I was not able to view the image in feed but in detail page the image is available. It was throwing an error

System.DmlException: Insert failed. First exception on row 0; first error: INVALID_CROSS_REFERENCE_KEY, Referenced file id is invalid, not accessible, or does not exist: [RawBody]

1 Answer 1


In case if image has been added to Rich Text Area field, its body will be stored as ContentReference record. If you look at rich field, format will be like:

<img alt="User-added image" src="https://......."></img>

Where src attribute contains link to image.

We can define PageReference and get its content by:

string richTxt = '<img alt="User-added image" src="https://c.naxx.content.force.com/servlet/rtaImage?..."></img>';
String imgRef = richTxt.substringBetween('src="', '"');
PageReference pageRef = new PageReference(imgRef);

Then insert ContentVersion record:

ContentVersion cVersion = new ContentVersion (title = 'title', VersionData = pageRef.getContent(), PathOnClient = 'my.png');
insert cVersion;

As you can see there is constant name, reason of that - ContentReference doesn't have name, I think using attachment will be better option

And create Feed:

FeedItem fItem = new FeedItem(RelatedRecordId = cVersion.id, type = 'ContentPost', parentId = '50036000000rxec');
insert fItem;

One more thing I want to mention here is - it's not allowed to insert ContentReference and Feed in single context, queueable can be used here.

Assuming everything above, we can implement following triggerHandler method:

public static void ProceedWithComments(set<id> caseIds) {

    list<Case> cases = [select id, Case_Comments__c from Case where id in :caseIds];

    map<id, ContentVersion> caseIdToContentMap = new map<id, ContentVersion> ();

    for (Case cs :cases){
        String imgRef = cs.Case_Comments__c.substringBetween('src="', '"').replace('amp;','');

        if (String.isNotBlank(imgRef)){
            PageReference pageRef = new PageReference(imgRef);
            ContentVersion cVersion = new ContentVersion (title = 'From Case', VersionData = pageRef.getContent(), PathOnClient = 'my.png');
            caseIdToContentMap.put(cs.id, cVersion);

    insert caseIdToContentMap.values();

    System.enqueueJob(new QueueableFeedInsert(caseIdToContentMap));


Queueable class:

public with sharing class QueueableFeedInsert implements Queueable {

    private map <id, ContentVersion> caseIdToContentMap;

    public QueueableFeedInsert(map<id, ContentVersion> caseIdToContentMap) {
        this.caseIdToContentMap = caseIdToContentMap;

    public void execute(QueueableContext context) {

        list<FeedItem> feedToInsert = new list<FeedItem>();

        for (Id csId :caseIdToContentMap.keySet()){
            feedToInsert.add(new FeedItem(RelatedRecordId = caseIdToContentMap.get(csid).id, type = 'ContentPost', parentId = csid));

        insert feedToInsert;


You must log in to answer this question.

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