Why did your GoHighLevel workflow send the same message twice?
A GoHighLevel workflow sends a message twice when the same person enters it twice, or when two workflows send the same thing. The usual causes are duplicate contact records, two triggers that both fire for one event, re-entry or multiple-opportunity settings that allow a second run, and appointment workflows, which always allow re-entry.
The settings behind most of these are described in HighLevel's workflow settings overview, updated September 3, 2026. The fix is rarely to rebuild the workflow. It is to find which of the causes below applies, using the contact's own history, and close that one door.
Double texts cost more than embarrassment. Every extra message raises opt-outs and spam reports, and a lead who gets two identical reminders starts to treat the third as noise.
How do you find which cause it is?
Open the contact that got the double message and read two things: the workflow history on the contact, and the conversation timeline. If the same workflow shows two enrollments, the contact entered twice. If two different workflows each sent one message, you have overlapping workflows. If there are two contact records for the same person, it is a duplicate contact.
Diagnose from the contact history
| What you see | Likely cause | Where to fix it |
|---|---|---|
| Two records with the same phone or email | Duplicate contacts | Duplicate settings and merge |
| One workflow, two enrollments minutes apart | Two triggers fired for one event | Workflow triggers and filters |
| One workflow, second enrollment days later | Allow Re-entry is on | Workflow settings |
| One enrollment per opportunity | Allow Multiple Opportunities is on | Workflow settings |
| Two workflows, same message | Overlapping workflows | Workflow inventory |
Are duplicate contacts causing it?
If the same person exists as two contacts, for example one created from a form with their email and one from a call with their phone number, each record can enter the workflow and each gets the message. Merging the records and setting how GoHighLevel matches incoming contacts stops it at the source.
It is a common cause in accounts that have grown over a few years, and it also distorts reporting, because one lead shows up as two. Our guide to common GoHighLevel mistakes covers the duplicate contact settings, and a GoHighLevel account cleanup merges existing duplicates before any workflow is changed.
Are two triggers firing for the same event?
A workflow can have several triggers, and if one event satisfies two of them, the contact can enter twice. A classic example is a "Form Submitted" trigger plus a "Contact Created" trigger: a new lead who fills in a form creates a contact and submits a form in the same second.
One event, two triggers
- Keep one trigger per real-world event, and add filters so each trigger only fires for its own case.
- Check for a trigger on "Contact Tag Added" when another workflow adds that tag as part of the same flow.
- Look for webhooks or Zapier steps that create or update the contact a second time.
Old campaigns and standalone triggers make this worse, because they may still run beside the workflow that replaced them. Our explainer on workflows vs triggers vs campaigns shows how to migrate and switch the old ones off.
Are the re-entry settings letting people back in?
With Allow Re-entry on, a contact who has completed the workflow can enter it again the next time the trigger fires. With it off, a contact can complete the workflow only once. Allow Multiple Opportunities lets one contact run the workflow once per opportunity. Appointment and invoice workflows always allow re-entry, whatever the setting says.
What each setting allows
That last rule, stated in HighLevel's settings guide, explains a lot of double reminders. A patient who books, cancels and rebooks has two appointments, so an appointment-triggered reminder workflow runs twice by design. Handle it inside the workflow instead: add an early step that checks the appointment status and ends the run if that appointment is cancelled.
- Nurture sequences: usually re-entry off, so a lead does not restart the sequence.
- Review requests: re-entry on only if a repeat customer should be asked again, with a wait period.
- Reminders: leave re-entry to the appointment rule, and filter by appointment status.
Are two workflows doing the same job?
In accounts built up over time, it is common to find a new workflow and an old one both sending a welcome text, or a snapshot workflow and a hand-built one both sending reminders. Each works on its own, and the customer gets both. The fix is an inventory: list every active workflow, what triggers it, and what it sends, and switch off duplicates.
Snapshots are a frequent source of this, because importing one adds its workflows beside the ones already in the account. Our page on whether pre-built snapshots are worth buying covers how to import one without doubling up. Stop rules help as a safety net: with Stop on Response on, a workflow ends for a contact who replies to one of its messages, so a reply never earns a second automated message.
How do you stop it happening again?
Name workflows by the event they handle, keep one owner workflow per event, test every change with a test contact before publishing, and review workflow history for a sample of contacts each month. Most duplicate messages start with a change nobody tested against the workflows already running.
If you want this done for you, it is part of every GoHighLevel automation build we do, and the Care Star Healthcare case study shows recurring automations running without manual clean-up.
What does a clean workflow setup look like?
One workflow owns each real-world event, its name says which event, and every workflow that sends messages has stop rules and a time window. With that structure a duplicate is easy to spot, because two workflows claiming the same event stand out in the list.
| Event | Owner workflow name | Re-entry | Stops when |
|---|---|---|---|
| New web enquiry | Lead / Web form / First response | Off | Reply, booking or opt-out |
| Appointment booked | Booking / Confirmation and reminders | Always (appointment rule) | Cancelled, rescheduled or attended |
| Job completed | Review / Request after visit | On, with a wait period | Review left or opt-out |
| No reply after 30 days | Nurture / Re-engage | Off | Reply, booking or opt-out |
The names are illustrative; the pattern is what matters. It also makes opt-out handling simpler, because every sending workflow is in one list you can check.
Questions about duplicate GoHighLevel messages
Can I stop a contact from being in two workflows at once?
Not with a single global setting. Add a filter or an early "if/else" step that checks a tag set by the other workflow, and end the run if it is present.
Why did a reminder go out after the appointment was cancelled?
The reminder workflow was already running when the appointment changed. Add a status check before each reminder step so cancelled appointments end the run.
Does turning off Allow Re-entry affect contacts already in the workflow?
It controls whether a contact can enter again after completing the workflow. Contacts currently in the workflow continue their run.
How do I test a workflow change safely?
Use a test contact with your own phone number and email, trigger the workflow the way a real lead would, and read the contact's workflow history before publishing to everyone.
Sources and further reading
- HighLevel, Workflow settings overview, updated September 3, 2026.
- HighLevel, Multiple opportunities toggle in workflows.
- HighLevel, Appointment scenarios in workflow.