On a specific date, I need to send one or more forms related to different tickets to the same contact.
To ensure that the form information is recorded in the correct ticket, we created a workflow that copies ticket-related properties to the contact associated with the submission. Once these properties are populated on the contact, another workflow is triggered, which sends the form through the Sales Emails feature.
After the form is sent by email, the ticket-related properties on the contact are cleared, preparing the contact for future form submissions.
The problem is that the contact may enter this process because of multiple different tickets, at the same time. When that happens, there isn’t enough time to copy the ticket information to the contact, send the email, and clear the contact properties before the next ticket enters the workflow. As a result, the contact properties can be overwritten, causing the wrong ticket information to be used.
How can I mitigate this issue?
Hi @dudacordeiro, This is a race condition, using contact properties as a temporary relay for ticket data breaks when multiple tickets hit the same contact close together, since there’s no locking between workflow runs. The real fix is to stop routing through contact properties entirely: instead, trigger the sales email directly from the ticket-based workflow using ticket properties in the personalization tokens, if Sales Email supports ticket-based enrollment, or use a custom-coded workflow step that sends the email via API with the ticket’s data passed directly in that single execution, never touching the contact record at all. That removes the shared state that’s causing the overwrite, since each ticket’s workflow run stays self contained instead of relying on a contact property both processes touch.
Hi @dudacordeiro and @Teetech,
Agreed, that’s a race condition. The issue is that the contact is being used as temporary storage for ticket data, so two workflows running at nearly the same time can overwrite each other’s values.
There are a couple of ways to avoid it:
Option 1: If you’re using automated marketing emails, consider enrolling the workflow on the ticket instead of the contact. Marketing emails can use ticket personalization tokens directly, so there’s no need to copy properties to the contact first.
Option 2: If that’s not possible and you want to stay no code, create a custom object record for each ticket submission and copy the ticket properties there instead. Each submission gets its own record, eliminating the shared state that causes the race condition. Then enroll the custom object in a workflow and send the automated email to the associated contact using the custom object’s properties for personalization.
If you’re using Sales Emails (1:1 templates) rather than automated marketing emails, that may explain why you introduced the contact property relay in the first place.
Hi @dudacordeiro,
From what you’re describing, it sounds like you should be able to skip the part of copying the ticket information to the contact record. In a ticket-based workflow, HubSpot lets you send an automated marketing email to the contact. that contains personalization tokens for the enrolled ticket: Send automated emails in workflows
When you add a personalization token, simply use the dropdown to change from the contact object to the ticket object.
If the email contains the link to a form, you can also pre-populate fields with ticket information, if needed, like I explained here: Pre-populate forms from mailing
I am not aware how this could be solved through sales emails - which frankly are not meant to be used that way and lack the capability to add ticket personalization tokens.
Best regards
Hey @dudacordeiro , that shared contact record is the weak point here. Keep each ticket’s details on the ticket instead. If your subscription supports it, use a ticket-based automated email with ticket properties, so each ticket keeps its own data. Test it with two tickets linked to the same contact before switching the live workflow.