I am trying to create a batch apex job that will find all tasks within a date range (for testing I have it set to one date), create a note (ContentNote) and link it to the whatid or whoid from the task (ContentDocumentLink) and then delete the task. I cannot get it to insert the note. I have been reading a lot of salesforce documentation and forums, but I have not found an answer. Do I have to create a content version?

Below is my code, any help would be appreciated. The error happens on line 32 - Database.SaveResult[] srList = Database.insert(newObjects, false);

global class archiveTasksBatch implements Database.Batchable<SObject>, Schedulable{

public final string query;
date mydate = date.today().addDays(-367);

public archiveTasksBatch() {
    query = 'Select WhoId, WhatId, Subject, Status, OwnerId, Id, Description, CreatedDate, ActivityDate From Task where ActivityDate = :mydate';
public void execute(SchedulableContext sc){
    Database.executeBatch(this, 100);
public Database.QueryLocator start(Database.BatchableContext bc){
    return Database.getQueryLocator(query);

public void execute(Database.BatchableContext bc, List<sObject> scope){
    list<ContentNote > newObjects = new list<ContentNote >();
    list<ContentDocumentLink  > newCDL = new list<ContentDocumentLink  >();

    for(Sobject s : scope){
        Task obj = (Task) s;
        String myString = obj.Description + obj.ActivityDate;
        Blob myBlob = Blob.valueof(myString.escapeHtml4());
        newObjects.add(new ContentNote (
        Title = obj.Subject,
        Content = myBlob
        system.debug('*********************************' +newObjects.size());
        system.debug('*********************************' +scope.size());

            Database.SaveResult[] srList = Database.insert(newObjects, false);
            for (Database.SaveResult sr : srList) {
                if(sr.isSuccess() && obj.WhatId != null) {
                    ContentDocumentLink cdl = new ContentDocumentLink();
                    cdl.ContentDocumentId = sr.getId();
                    cdl.LinkedEntityId = obj.WhatId;
                    cdl.Visibility = 'AllUsers';
                    cdl.ShareType = 'V';
                if(sr.isSuccess()&& obj.WhoId != null) {
                    ContentDocumentLink cdl2 = new ContentDocumentLink();
                    cdl2.ContentDocumentId = sr.getId();
                    cdl2.LinkedEntityId = obj.WhoId;
                    cdl2.Visibility = 'AllUsers';
                    cdl2.ShareType = 'V';

        insert newCDL;
    catch(Exception e) {

    delete scope;

public void finish(Database.BatchableContext bc){
    system.debug('JOB IS FINISHED');


UPDATE - I found that when I had accidentally set LinkedEntityId to the task id (first time I ran it) it worked. It created the note and deleted the tasks. However, since I linked it to the task none of the notes are linked to a record. So, at one point it "worked". Also, now when I try to create a note using the button on the contact I get the error "ContentPublication Limit exceeded." which, I am assuming, is why I can no longer create the note from the batch - hence the error there. I am clueless as to what to do next, found some more documentation to read through - in the meantime, if you have any help I would love to hear it.


1 Answer 1


There is a post in System.UnexpectedException: Note can't be saved that suggests String.escapeHTML4() is not sufficient to set the ContentNote.Content field. They've even gone as far as creating a github project to correct for it. - DMRNoteAttachmentImporter

The following steps are required to prepare note content for insertion into Salesforce:

  1. Replace all basic HTML characters (<>"'&) with their corresponding entities (& and friends).
  2. Replace all line breaks with <br> (taking care with Windows CRLF/Linux LF/Mac CR)
  3. Replace ' with &#39;.
  4. Do not replace Unicode characters with entities. Other entities, including &apos;, result in an exception. Unicode should be left as the bare characters.
  5. Ensure that the source content is well-formed Unicode/UTF-8 and does not contain non-printable characters.
  6. The title must not be null, zero-length, or consist only of whitespace. The title need not be escaped.

All but (5) are handled by this package. You are responsible for ensuring that supplied text is well-formed.

At the very least, check the characters you are trying to insert into the Content. There are likely to be encoding issues.

  • Thanks for the fast reply!I read through that and tried just setting the content to just "test". I was still getting the error. I did just update my question. I may have a different issue than I originally thought. May 16, 2017 at 21:17

You must log in to answer this question.

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