Salesforce’s Visual Workflow and Process Builder are incredibly powerful tools but can be very difficult to troubleshoot. I struggled to make these tools effective until I was able to get a glimpse of what was happening inside. Salesforce has some suggestions for how to troubleshoot failing flows but often these tools provide incomplete answers. Particularly for auto launched flows, these techniques are often insufficient.
Debug log to the rescue!
Thankfully Salesforce has made a few updates over the years that makes viewing the internal state of flow a little easier. Particularly one can see variable assignment, loop behaviour and more detailed error logging.
The debug log is a veritable garden of detail about the internal state of Salesforce, including info about:
- Database Changes
- Workflow ( Workflow rules, Assignment rules, Approval processes, Process builder, visual workflow)
- Callout (such as HTTP callouts)
- Apex Code
- Apex Profiling (used to show limits while running apex)
In the debug log you will see messages grouped into the above log categories. These log categories each have a adjustable level of detail. Meaning one can tune the logging that takes place in order in order to get a uncluttered log. Workflow is the log category that we are most concerned about when troubleshooting flows and process builder.
Something that I failed to understand about debug logging for a long time is that the logging is driven by individual user’s actions. One can manually set a log trace to follow the actions of more than one user at a time, however in practice it is very difficult to log the events of more than a few users at a time within Salesforce.
Salesforce Makes Debugging Easy
Fortunately Salesforce has done something clever to make setting a user log trace very quick and easy. The system will automatically set a debug logging level for your user whenever you open the debug console. This means debug setup is easy as opening up the developer console, then making making one adjustment within Salesforce setup.
The different debug log level options are:
- Info (Default for workflows when using the native dev console logging level)
Notice the default logging level for the Workflow log category, it’s set to ‘Info’. Changing these log levels adjusts how much detail is captured for each log category. ‘Info’ covers some of what we need for flows and process builder but it’s lacking the most useful actions. See the table at the bottom of this post for all the available actions. For example to see when and how a flow is completing a variable assignment, one needs to adjust the level to ‘finer’.
1. First Time Logging Setup
- Open the Developer Console.
- This will begin logging for your user for 30 minutes.
- Go back to your main Salesforce window and navigate to SF classic: Setup Quick Search –> ‘Debug level’.
- Edit the SFDC_DevConsole logging level.
- Opening the dev console created this logging level, now let’s adjust it be appropriate for your needs.
- Slowly dial up the level of logging from ‘info’ to higher levels of logging and observe which different actions are shown.
- I would suggest starting with workflow on ‘finer’, adjust as needed.
2. Log That Automation
Once you have the debug level set- your tooling is all ready, it’s time to actually troubleshoot. Given that the native debug logging captures for your own user and only your user, you need to fire your automation. This can happen by any of the following ways:
- Complete the triggering actions within SF to trigger the automation.
- If your process is an auto launched flow consider the ‘execute’ button.
- For process builders and auto launched flows one can write and run tests. Test driven development has many advantages, getting access to logging quickly is just one of the many.
3. Find that Bug:
View Logs and Quick Edit Logging Levels
To understand how to view your logs after executing your automation please see this trailhead, it has a great explanation of how to view your log files. It also covers how to adjust logging levels within the dev console itself, which is a real time saver. The first time setup above is useful to understand the logging levels as a concept but is a little clunky to navigate on a day to day basis.
4. Don’t Overlook Performance
Keep in mind that logging isn’t completely free, there are some consequences when using these tools. Logging will consume CPU time, if you are using this tool to troubleshoot performance know that this logging will consume some of your execution limits.
There is a 2MB file size limits on any single log. Turning everything to ‘Finer‘ is a recipe for trouble to overrun that file size. Only log what you need, I have yet to run into a scenario where I need super detailed debugging across all categories at once.
Reference: Workflow Log Event Types
The bolded actions are those that are not covered by the default ‘info’ debugging level.
|Event Name||Fields or Information Logged with Event||Level Logged|
|FLOW_ACTIONCALL_DETAIL||Interview ID, element name, action type, action enum or ID, whether the action call succeeded, and error message||FINER and above|
|FLOW_ASSIGNMENT_DETAIL||Interview ID, reference, operator, and value||FINER and above|
|FLOW_BULK_ELEMENT_BEGIN||Interview ID and element type||FINE and above|
|FLOW_BULK_ELEMENT_DETAIL||Interview ID, element type, element name, number of records, and execution time||FINER and above|
|FLOW_BULK_ELEMENT_END||Interview ID, element type, element name, and number of records||FINE and above|
|FLOW_CREATE_INTERVIEW_BEGIN||Organization ID, definition ID, and version ID||INFO and above|
|FLOW_CREATE_INTERVIEW_END||Interview ID and flow name||INFO and above|
|FLOW_CREATE_INTERVIEW_ERROR||Message, organization ID, definition ID, and version ID||ERROR and above|
|FLOW_ELEMENT_BEGIN||Interview ID, element type, and element name||FINE and above|
|FLOW_ELEMENT_DEFERRED||Element type and element name||FINE and above|
|FLOW_ELEMENT_END||Interview ID, element type, and element name||FINE and above|
|FLOW_ELEMENT_ERROR||Message, element type, and element name (flow runtime exception)||ERROR and above|
|FLOW_ELEMENT_ERROR||Message, element type, and element name (spark not found)||ERROR and above|
|FLOW_ELEMENT_ERROR||Message, element type, and element name (designer exception)||ERROR and above|
|FLOW_ELEMENT_ERROR||Message, element type, and element name (designer limit exceeded)||ERROR and above|
|FLOW_ELEMENT_ERROR||Message, element type, and element name (designer runtime exception)||ERROR and above|
|FLOW_ELEMENT_FAULT||Message, element type, and element name (fault path taken)||WARNING and above|
|FLOW_INTERVIEW_PAUSED||Interview ID, flow name, and why the user paused||INFO and above|
|FLOW_INTERVIEW_RESUMED||Interview ID and flow name||INFO and above|
|FLOW_LOOP_DETAIL||Interview ID, index, and value
The index is the position in the collection variable for the item that the loop is operating on.
|FINER and above|
|FLOW_RULE_DETAIL||Interview ID, rule name, and result||FINER and above|
|FLOW_START_INTERVIEW_BEGIN||Interview ID and flow name||INFO and above|
|FLOW_START_INTERVIEW_END||Interview ID and flow name||INFO and above|
|FLOW_START_INTERVIEWS_BEGIN||Requests||INFO and above|
|FLOW_START_INTERVIEWS_END||Requests||INFO and above|
|FLOW_START_INTERVIEWS_ERROR||Message, interview ID, and flow name||ERROR and above|
|FLOW_SUBFLOW_DETAIL||Interview ID, name, definition ID, and version ID||FINER and above|
|FLOW_VALUE_ASSIGNMENT||Interview ID, key, and value||FINER and above|
|FLOW_WAIT_EVENT_RESUMING_DETAIL||Interview ID, element name, event name, and event type||FINER and above|
|FLOW_WAIT_EVENT_WAITING_DETAIL||Interview ID, element name, event name, event type, and whether conditions were met||FINER and above|
|FLOW_WAIT_RESUMING_DETAIL||Interview ID, element name, and persisted interview ID||FINER and above|
|FLOW_WAIT_WAITING_DETAIL||Interview ID, element name, number of events that the element is waiting for, and persisted interview ID||FINER and above|
Thomas George is a Freelance Salesforce Administrator/ Developer. For two years he has been helping businesses solve problems with Salesforce.