Skip to main content

#Triggers6 discussing

Hi everyone! 

 

I am currently trying to do a deployment and using a new type of email trigger and ran into this error but there are recipients; I believe the manifest is missing something but I do not know the exact text/API that should be used.  Can you please help?  

 

Deployment Issue with Email Triggerimage.pngimage.png

 

 

image.png

 

 

image.png

 

 

 

 

#Flows  #Triggers  #Deployment

3 answers
0/9000

I have a trigger and a apex class that should be showing a custom message when a user tries to upload a file on a record related list when the file name has too many characters. But when i test it, it shows the standard  Can't upload message. I'm not sure what I am doing wrong 

 

trigger tr_ContentVersionTrigger on ContentVersion (before insert) {

charContentVersionTriggerHandler.validateFileNameLength(Trigger.new);

}

public with sharing class charContentVersionTriggerHandler {

private static final Integer MAX_CHAR_LIMIT = 80;

public static void validateFileNameLength(List<ContentVersion> newFiles) {

for (ContentVersion file : newFiles) {

if (file.Title != null && file.Title.length() > MAX_CHAR_LIMIT) {

String errorMessage = 'The file name "' + file.Title +

'" exceeds the maximum system limit of ' + MAX_CHAR_LIMIT +

' characters. Please rename the file and try again.';

file.addError(errorMessage);

}

}

}

}

 

#Apex  #Triggers

1 answer
  1. Oct 23, 8:12 PM

    Your trigger is most likely firing fine. The catch is the Upload Files dialog on the related list doesn't show the text from addError on ContentVersion, it just replaces it with its own generic "Can't upload" message. You can confirm by turning on a debug log for your user and uploading a file with a long name, your message should show up in the log. 

    If blocking isn't a hard requirement, an easier route is to shorten the name in the same before insert instead of throwing an error, so the upload just goes through:

    if (file.Title != null && file.Title.length() > MAX_CHAR_LIMIT) { 

        file.Title = file.Title.left(MAX_CHAR_LIMIT); 

    } 

     

    Title doesn't include the extension (that's on PathOnClient / FileExtension), so the file still opens normally. If you do need to block it, it's probably worth adding a note near the related list so users know about the 80 character limit, since they won't see your custom text.

0/9000

🔥 Salesforce Apex & Trigger Best Practices

Writing Apex and Triggers the right way makes your org scalable, maintainable, and future-ready 🚀

✅ Apex Best Practices

  • Bulkify your code (always handle multiple records)
  • Avoid SOQL/DML inside loops
  • Use collections (Set, Map, List) efficiently
  • Follow proper exception handling
  • Write meaningful test classes (aim for quality, not just coverage)
  • Use @future / Queueable for async processing

⚡ Trigger Best Practices

  • One trigger per object
  • Keep triggers logic-free (use Trigger Handlers)
  • Use context variables wisely (before/after, insert/update/delete)
  • Prevent recursion using static variables
  • Make triggers bulk-safe & reusable

👉 Clean code today = Fewer issues tomorrow

 

🔥 Salesforce Apex & Trigger Best PracticesWriting Apex and Triggers the right way makes your org scalable, maintainable, and future-ready 🚀✅ Apex Best PracticesBulkify your code (always handle multi

 

#Salesforce Developer #Apex #Triggers s  #Salesforce #SFDC Admin Certification #TrailblazerCommunityHelp #Trailhead Challenges #Agentforce

0/9000

I wrote trigger on Account object, When I test the Trigger it was working fine when I entered the the record manually., But Trigger is not fired when the data is coming through integration even it passing all the criteria. Please help me why the trigger is not firing

. #BatchClass, #Batchapex, #Triggers,@developers

7 answers
  1. Jul 22, 2025, 10:57 AM

    Hi Naveen, 

     

    Check the following things, 

     

    API User Permissions: Verify that the integration user has the necessary permissions to trigger the logic. 

    Integration Method: Ensure the API method used (like create, update) aligns with your trigger logic. 

     

    please mark this answer helpful if it solved your query.

     

     

     

     

     

    Arun Goel

    Oct 1, 2024, 7:40 PM

     

     

     

    Hi Naveen, 

      

    Check the following things, 

      

    API User Permissions: Verify that the integration user has the necessary permissions to trigger the logic. 

    Integration Method: Ensure the API method used (like create, update) aligns with your trigger logic. 

      

    please mark this answer helpful if it solved your query.

     

     

     

     

     

    Arun Goel

    Oct 1, 2024, 7:40 PM

     

     

     

    Hi Naveen, 

      

    Check the following things, 

      

    API User Permissions: Verify that the integration user has the necessary permissions to trigger the logic. 

    Integration Method: Ensure the API method used (like create, update) aligns with your trigger logic. 

      

    please mark this answer helpful if it solved your query.

0/9000

Create a trigger that calculates and updates a custom field on the Account object named TotalOpportunityValue whenever an Opportunity related to that Account is created, updated, or deleted. The field should represent the sum of the Amount field of all related Opportunities.

 

#Triggers

5 answers
  1. Jan 13, 2025, 10:56 AM

    Hello @Swati Patle

     

    You can take reference from below code.

     

    Trigger TotalOpportunityAmount on Opportunity (after insert,after update,after delete,after undelete ) {

    List<Account> oppListToIterate = Trigger.isDelete ? Trigger.old : Trigger.New;

    List<Account> accountListToUpdate = new List<Account>();

    set<Id> accountIds=new set<Id>();

    for(Opportunity opp:oppListToIterate){

    if((Trigger.isInsert || Trigger.isDelete) && opp.ExpectedRevenue != null )

    accountIds.add(opp.accountID);

    else if(Trigger.isUpdate && (opp.ExpectedRevenue != Trigger.oldMap.get(opp.Id).ExpectedRevenue)){

    accountIds.add(opp.accountId);

    }

    else if(Trigger.isUpdate && (opp.AccountId != Trigger.oldMap.get(opp.Id).AccountId)){

    accountIds.add(opp.accountId);

    accountIds.add(Trigger.oldMap.get(opp.Id).accountId);

    }

    }

    for(AggregateResult ar : [SELECT AccountId AcctId,SUM(ExpectedRevenue) totalRevenue FROM Opportunity WHERE AccountId in :accountIds group by AccountId]){

    accountListToUpdate.add(

    new Account(

    Id = (Id) ar.get('AcctId'),

    TotalRevenue__c = (Integer) ar.get('totalRevenue');

    )

    );

    }

    if(!accountListToUpdate.isEmpty())

    UPDATE accountListToUpdate;

    }

    In case you find any other issue please mention. 

    If you find your Solution then mark this as the best answer. 

0/9000

Design a trigger to automatically assign new Case records to specific users based on the Case's Type field. For example, Cases of type 'Technical Support' should be assigned to User A, and Cases of type 'Billing' should be assigned to User B.

 

#Triggers

2 answers
  1. Dec 15, 2024, 5:22 PM

    Hii,

    It's better if you share the approach you followed.

    However, you can use something like this in your trigger handler

     

     //You can fetch the user Ids through query and use them instead of hardcoding

     Id userAId = 'xxxxxxxxxxxx'; // User A's Salesforce ID

     Id userBId = 'xxxxxxxxxxxx'; // User B's Salesforce ID

     

     // Loop through all the Case records being inserted

     for (Case newCase : Trigger.new) {

     

     // Check the 'Type' field to determine which user should be assigned

     if (newCase.Type == 'Technical Support') {

     newCase.OwnerId = userAId; // Assign to User A

     } else if (newCase.Type == 'Billing') {

     newCase.OwnerId = userBId; // Assign to User B

     } else {

     // newCase.OwnerId = defaultUserId;

     }

     }

0/9000

trigger CaseDeleted on Case (before delete) 

{

   //Whenever a case is getting deleted check if it has the contact is related account

   // If it is related to the account and contact then throw an error saying "can not be deleted"

   for (Case cs: Trigger. old);

   {

       if(case.Accountid !=Null && case.Contactid !=Null) // if case is releted Account and Contact

       

       {

       case.adderror('we can not delete case Releted Account And Contact');

       }

   }

}

Explain The Execution

2 answers
  1. Nov 18, 2024, 2:58 PM

    Hi,

    The trigger prevents the deletion of a Case record if it is associated with both an Account and a Contact. Before the record is deleted, the trigger checks whether the Case has non-null values for both the AccountId and ContactId. If both are present, the trigger calls addError() on the Case record, which stops the deletion and displays an error message to the user, indicating that the Case cannot be deleted because it is linked to both an Account and a Contact.

    The issue in your code is semicolon after for loop,the code should be :

    trigger CaseDeleted on Case (before delete) {

     

    // Loop through each case in the trigger's old context (cases that are being deleted)

    for (Case cs : Trigger.old) {

     

    // Check if both AccountId and ContactId are populated

    if (cs.AccountId != null && cs.ContactId != null) {

    // If the case is related to both an Account and a Contact, throw an error to prevent deletion

    cs.addError('Cannot delete case related to both an Account and a Contact.');

    }

     

    }

     

    }

    Mark this helpful if it solves your query!

0/9000

Write a trigger that prevents the insertion of an Account if the Account's Annual Revenue is less than $50,000. The trigger should also prevent updates that would set the Annual Revenue to less than $50,000.

 

#Triggers

5 answers
  1. Nov 7, 2024, 6:17 AM

    Hi Swati,

    Try this:

    trigger PreventLowAnnualRevenue on Account (before insert, before update) {

    // Iterate through each Account record in the trigger context

    for (Account acc : Trigger.new) {

     

    // Check for insert operation

    if (Trigger.isInsert) {

    // Prevent insert if AnnualRevenue is less than $50,000

    if (acc.AnnualRevenue != null && acc.AnnualRevenue < 50000) {

    acc.addError('Annual Revenue cannot be less than $50,000.');

    }

    }

     

    // Check for update operation

    if (Trigger.isUpdate) {

    // Prevent update if AnnualRevenue is being set below $50,000

    Account oldAcc = Trigger.oldMap.get(acc.Id);

    if (acc.AnnualRevenue != oldAcc.AnnualRevenue && acc.AnnualRevenue < 50000) {

    acc.addError('Annual Revenue cannot be set to less than $50,000.');

    }

    }

    }

    }

    Mark this helpful if it solves your query!

0/9000

Want create CSV file from APEX

 

Hi All,

 

Hope you doing well. I am trying create CSV file from apex class. Where i am getting the object name from custom label and depend on the label i query all the fields of that object and then store the object API name and all the fields in  Single Object Data Storage custom object and after that depends on the fields trying create a CSV file and try to store that csv file in Single Object Data Storage custom object attachment.

 

Example: in Custom Label having "Account" api name, so when i run the class, it query all the fields of account and create a record in Single Object Data Storage custom object with "Account" name and the account fields. And after using that query fields i am creating the CSV and store in the same  Single Object Data Storage custom object record. 

 

As of now, everything working fine, i can able to create the CSV file and store it in Single Object Data Storage custom object, but the CSV file data are not coming proper way. I understand where is the issue but can't find a way to fix it. If anyone can help?

Here is excel screenshot i am getting:

 

Want create CSV file from APEX Hi All, Hope you doing well. I am trying create CSV file from apex class.

 

Below is my code:

public class SingleObjectDataStoreCls {

    

    public static void SingleObjectDataStoreMtd() {

        

        ID singleObjDataStorageID;

        List<String> NameFiled = new List<String>();

        Map <String,Schema.SObjectType> gd = Schema.getGlobalDescribe();

        

        //Custom label for SObjcet api name: System.label.SObject_Name

        Schema.SObjectType sobjType = gd.get(System.label.SObject_Name);

        Schema.DescribeSObjectResult r = sobjType.getDescribe();

        Map<String, Schema.SObjectField> MapofField = r.fields.getMap();

        

        for(String fieldName : MapofField.keySet()) 

        {

        Schema.SObjectField field = MapofField.get(fieldName);

        Schema.DescribeFieldResult F = field.getDescribe();

        NameFiled.add(F.getName());  

        }        

        System.debug('Field Name:***2 '+NameFiled);

 

        String allstring = String.join(new List<String>(NameFiled), ', ');

        System.debug(allstring);

        

//Single Object Data Storage custom object

        Single_Object_Data_Storage__c singleObjDataStorage = new Single_Object_Data_Storage__c();

        singleObjDataStorage.Fields_api_name_of_selected_object__c= allstring; //adding object fileds from query

        singleObjDataStorage.Object_API_name_of_selected_object__c = System.label.SObject_Name; //adding object name from query

        insert singleObjDataStorage;

        System.debug('Sujay1 singleObjDataStorage '+singleObjDataStorage);

        

        singleObjDataStorageID = singleObjDataStorage.Id;

        System.debug('Sujay1 singleObjDataStorageID '+singleObjDataStorageID);

                

        //get fields values

        SObject[] singleObjDataStorages = Database.query('SELECT ' + singleObjDataStorage.Fields_api_name_of_selected_object__c + ' FROM ' +System.label.SObject_Name );

 

        //create CSV

        String title = System.label.SObject_Name;

        String csvFile;

        String csvColumnHeader = singleObjDataStorage.Fields_api_name_of_selected_object__c+', Type\n';

        List<String> csvRowValues = new List<String>();

 csvFile = csvColumnHeader + String.join(singleObjDataStorages,'\n');

        

        title += '.csv';

        

        createFile(csvFile, title, singleObjDataStorageID);

    }

    

    public static void createFile(String csvFile, String title, Id singleObjDataStorageID) {

        

        ContentVersion cv = new ContentVersion();

        cv.ContentLocation = 'S'; 

        cv.Title = title; 

        cv.PathOnClient = title; 

        cv.VersionData = Blob.valueOf(csvFile); //file data

        insert cv;

        

        Attachment attachment = new Attachment();

        attachment.ParentId = 'a04J2000009p0aBIAQ';

        attachment.Name = cv.PathOnClient;

        attachment.Body = cv.VersionData;

        insert attachment;

    }

 

}

 

#Apex  #Salesforce Developer  #Triggers  #LWC

 

#Apex  #Salesforce Developer  #Salesforce  #Triggers  #LWC

1 comment
  1. Aug 30, 2024, 10:17 AM

    OK While you are creating CSV you must be careful about these things in your data:

    - Comma inside data

    - New line and Line feed values.

    As well as I see you are only assigning   Database.query results as CSV, you should do in loop and control the values inside fields.

     

     SObject[] singleObjDataStorages = Database.query('SELECT ' + singleObjDataStorage.Fields_api_name_of_selected_object__c + ' FROM ' +System.label.SObject_Name );

0/9000

🔍 Seeking Advice from Salesforce Wizards 🔍

 

Hey, Salesforce experts!

I'm currently tackling a tricky logic puzzle in Salesforce, and I could use some guidance.

 

Here's the scenario: I have a requirement to ensure that two lookup fields on a record maintain a one-to-one mapping. To accomplish this, I've implemented a before insert/update trigger to enforce the mapping. Additionally, I've set up a validation rule to prevent changes to the lookup fields once they are populated.

 

Now, according to Salesforce's order of execution, validation rules should run before triggers. However, I'm encountering a situation where the trigger error is firing first, even though I expect the validation rule to take precedence, when i am trying a update a lookup field after it's already populated.

 

Feel free to drop your thoughts in the comments below or reach out to me directly. Your expertise could be the missing piece of the puzzle!

 

#Salesforce Developer  #Automation  #Apex  #Triggers  #Validation Rule  #Validation Rules

1 comment
  1. May 14, 2024, 10:04 PM

    Hi @Adarsh Agrawal,

     

    Please refer to the documentation below.

     

    Triggers and Order of Execution | Apex Developer Guide | Salesforce Developers

     

    1. Salesforce performs different validation checks depending on the type of request.
      • For requests from a standard UI edit page, Salesforce runs these system validation checks on the record:
        • Compliance with layout-specific rules
        • Required values at the layout level and field-definition level
        • Valid field formats
        • Maximum field length
      • Additionally, if the request is from a user object on a standard UI edit page, Salesforce runs custom validation rules.
      • For requests from multiline item creation such as quote line items and opportunity line items, Salesforce runs custom validation rules.
      • For requests from other sources such as an Apex application or a SOAP API call, Salesforce validates only the foreign keys and restricted picklists. Before executing a trigger, Salesforce verifies that any custom foreign keys don’t refer to the object itself.
    2. Executes record-triggered flows that are configured to run before the record is saved.
    3. Executes all before triggers.
    4. Runs most system validation steps again, such as verifying that all required fields have a non-null value and runs any custom validation rules.

    Please check the fourth point.

     

    Thanks!

0/9000