aibrevo
Checklist flowchart for diagnosing a GoHighLevel workflow that isn't triggering

GoHighLevel Workflow Not Triggering? A Systematic Troubleshooting Guide

A step-by-step process for diagnosing why a GoHighLevel workflow isn't firing: toggle state, trigger events, filters, re-entry settings, if/else branches, delays, and activity logs.

Key takeaways

  • The single most common cause of a silent workflow is a mismatch between what the trigger is configured to listen for and what actually happened to the contact — a tag trigger set to 'Tag Added' won't fire if the tag was already present before the workflow was published.
  • Re-entry settings, not the trigger itself, are the usual explanation when a workflow fired once for a contact and then goes quiet on every subsequent qualifying event — if re-entry is off, that contact is permanently done with the workflow until manually removed.
  • Filters inside the trigger and filters inside if/else branches are evaluated separately, so a contact can correctly satisfy the trigger and still fall out of the workflow at the first branch if branch conditions reference a field that was never populated.
  • The workflow's own Enrollment History and Execution Logs (not the contact's activity tab) are the fastest way to tell whether a contact was ever evaluated against the trigger at all, versus evaluated and filtered out, versus enrolled and stuck on a delay or action step.
  • A workflow left in Draft status will accept manual test runs from the builder but will not fire from live triggers — this single toggle explains a large share of 'it worked in testing but not for real contacts' reports.
  • Escalating to GoHighLevel support is worth doing only after ruling out configuration causes locally, and support tickets move faster when they include the specific contact ID, workflow ID, and a timestamp of the expected trigger event.

A GoHighLevel workflow that isn’t triggering almost never means the platform is broken. It usually means one specific setting, out of a dozen possible ones, doesn’t match what you assumed it did: the toggle is still on Draft, the trigger event doesn’t match what actually happened to the contact, a filter or if/else branch is silently routing contacts away from the action steps, or re-entry is turned off so a contact who already ran through the workflow once is permanently excluded. The fix is almost always fast once you find the mismatch. Finding it fast means checking things in the right order instead of guessing.

This guide walks through that order: publish status, trigger event matching, filters, re-entry settings, branch logic, delay steps, and the two log views that tell you exactly where a contact got stuck. If you’re building or rebuilding GoHighLevel automations as part of a broader setup, the GoHighLevel implementation services page covers how a properly tested automation layer fits into a full build.

Start with the toggle: is the workflow actually published?

Before checking anything else, confirm the workflow status shown at the top of the builder. GoHighLevel workflows have three relevant states: Draft, Published, and Paused (sometimes shown as inactive). Only a Published workflow evaluates live trigger events and enrolls real contacts.

This sounds too basic to be a real cause, but it’s a common one specifically because Draft workflows still let you run manual test enrollments from inside the builder. A builder tests a workflow by manually adding a test contact, watches it run correctly, and assumes it’s live, without noticing the status toggle never got flipped to Published. The workflow behaves perfectly for manual tests and does nothing for actual leads.

Check this first because it eliminates an entire category of possible causes in a few seconds. If the workflow shows Published and contacts still aren’t enrolling, move to the trigger configuration itself.

Confirm the trigger event actually matches what happened

The next most common cause is a mismatch between the trigger’s configuration and the real-world event it’s supposed to catch. GoHighLevel offers trigger types including tag added, tag removed, form submitted, pipeline stage changed, appointment booked, and several others, and each one listens for a specific event, not a general state.

The classic version of this mistake: a workflow is set to trigger on “Tag Added,” but the contact already had that tag applied before the workflow was published or before the automation step that’s supposed to apply it ran. Since the tag wasn’t newly added after the trigger went live, the event never fires for that contact, even though the contact currently has the tag. The same logic applies to pipeline stage triggers: a contact moved into a stage before the trigger existed, or moved there through a bulk import rather than a stage-change action, may not generate the discrete “stage changed” event the trigger is listening for.

Verify this by checking the exact trigger type and its configured value against what actually happened, in what order, for a specific test contact. If the tag or stage change happened before the workflow went live, or happened through an import rather than a live action, that’s very likely your answer.

Check filters inside the trigger step

Beyond the trigger event itself, most trigger steps allow additional filter conditions layered on top, such as requiring a specific tag, a particular pipeline, or a custom field value. These filters are evaluated as a separate condition from the trigger event, and a contact who satisfies the event but fails a filter will not enroll.

A frequent source of confusion here is a filter referencing a custom field that isn’t populated for every contact entering the funnel. If a filter checks “Lead Source equals Facebook” and a batch of contacts came in through a different form where that field was never mapped, those contacts fail the filter silently. There’s no error message; the contact simply doesn’t enroll, and from the outside it looks identical to the trigger itself not firing.

Review each filter condition attached to the trigger individually, and check a real contact record to confirm the referenced field or tag is actually present and spelled the way the filter expects. Field name mismatches (an extra space, a different capitalization from an old snapshot) are a quiet but common cause of filtered enrollments.

Checking a single contact only tells you about that one contact’s data, which can be misleading if the field happens to be populated for them but not for the broader batch. Pull three or four contacts who should have entered the workflow around the same time and compare the referenced field or tag across all of them. If the field is populated for some and blank for others, that inconsistency, not the filter logic itself, is usually the real problem, and it often traces back to different lead sources or forms feeding the same pipeline without mapping to the same custom field.

Re-entry settings: why a workflow fires once and then goes silent

Re-entry is one of the most misunderstood settings in GoHighLevel workflow configuration, and it’s the usual explanation for a workflow that clearly worked for the first contact or two and then appears to stop working for everyone after.

Every workflow has a re-entry setting in its Settings tab, controlling whether a contact who has already been enrolled (or already completed the workflow) can be enrolled again when they satisfy the trigger a second time. If re-entry is set to off, once a contact goes through the workflow, that contact is done, permanently, regardless of how many more times they’d otherwise qualify for the trigger. This is often the correct behavior (you don’t want a welcome sequence firing every time a returning customer re-tags themselves), but it becomes a troubleshooting trap when a builder tests a workflow with the same contact repeatedly and can’t understand why the second or third test run does nothing.

Fix this during testing by using a fresh test contact for each test run, or by explicitly setting re-entry to allow multiple entries while testing, then reverting it to the intended production setting once the workflow logic is confirmed. In production, decide re-entry deliberately based on what the workflow is for: a one-time onboarding sequence should typically block re-entry, while a review-request workflow tied to repeat appointments usually needs to allow it.

If/else branches apply their own logic, separate from the trigger

Once a contact is enrolled, if/else branch steps inside the workflow apply additional condition checks, and these are evaluated independently of whatever got the contact into the workflow in the first place. A contact can correctly pass the trigger and any trigger-level filters, and still exit the workflow at the very first branch if the branch condition checks something that isn’t true, or isn’t populated, for that contact.

This shows up most often when a branch checks a custom field value (say, “appointment type equals consultation”) and the contact came in through a path where that field was never set. The branch doesn’t error; it just routes the contact down the “else” path, which may lead to an end step with no further action, making the workflow look like it did nothing.

Diagnosing this means opening the specific contact’s path through the workflow (covered below in Execution Logs) and checking exactly which branch they took and why. If contacts are consistently landing in an unexpected branch, the fix is either correcting the branch condition or fixing the upstream step that’s supposed to populate the field the branch depends on.

Delay steps: the silent holding pattern

A delay step that appears to do nothing is often working exactly as configured, just not the way the builder expected. Delay steps can be set in minutes, hours, or days, and a duration typo (days instead of hours) can hold a contact for what looks, from the outside, like indefinite inaction.

Delay steps can also be configured to resume execution only during specific business hours or at a specific time of day, based on the sub-account’s configured time zone. A contact who hits the delay step outside those hours will wait until the next valid window, which can look like a stalled workflow if the tester isn’t aware the time restriction exists. Confirm both the duration and any time-of-day restriction, and confirm the sub-account’s time zone setting matches what’s actually expected.

If a delay step references a specific date field (for example, “wait until appointment date”) rather than a fixed duration, an empty or malformed date field for that contact can cause the delay to behave unpredictably rather than throwing a visible error.

Use Enrollment History and Execution Logs before guessing further

GoHighLevel provides two views inside the workflow builder that are more useful for diagnosis than checking a contact’s individual activity tab: Enrollment History and the per-contact Execution Log.

Enrollment History, accessible from the workflow’s own menu, lists every contact who was evaluated against the trigger, whether they enrolled, and if not, why they were filtered out. This is the fastest way to answer the most important diagnostic question: was the contact ever evaluated at all? If a contact doesn’t appear in Enrollment History, the trigger event itself never fired for them, which points back to the trigger-matching and publish-status checks above. If the contact does appear but shows as filtered, the filters covered earlier are the likely cause.

For a contact who did enroll, the Execution Log for that specific contact shows exactly which step they’re on, which branch they took at each if/else, and how long they’ve been sitting on a delay step. This is the right tool for diagnosing the branch and delay issues covered above, rather than guessing from the workflow’s visual layout.

Run a clean test contact through the entire workflow

Once the individual settings above have been checked, the most reliable confirmation is a controlled end-to-end test: create a fresh contact with none of the tags, field values, or pipeline history that could trigger unrelated automations, and manually walk that contact through the exact conditions the trigger is supposed to catch. Watch it through Enrollment History and the Execution Log in real time rather than waiting and checking later.

Testing with a fresh contact avoids the re-entry trap covered earlier and gives a clean read on whether the trigger, filters, branches, and delays behave as configured when nothing else about the contact’s history could be interfering. If a workflow behaves correctly for a clean test contact but not for real leads, the difference is almost always in the real leads’ existing tags, field values, or enrollment history, not in the workflow logic itself.

When to escalate to GoHighLevel support

Configuration issues explain the large majority of workflows that appear not to trigger, which is why working through the checks above first, rather than opening a support ticket immediately, resolves most cases faster. Escalation is worth it when Enrollment History shows a contact was never evaluated despite a trigger event that clearly should have matched, since that can point to a platform-side delay in event processing or an issue with how a specific trigger type is registering events for that sub-account.

When escalating, include specifics: the workflow ID, the exact trigger configuration, a specific contact ID used for testing, and the timestamp of the event that should have fired the trigger. GoHighLevel’s help center documents expected behavior for each trigger type, which is a useful reference to confirm your configuration matches documented behavior before assuming it’s a platform bug rather than a setup issue.

The bottom line on non-triggering workflows

A GoHighLevel workflow that isn’t firing is a diagnostic problem with a defined checklist, not a mystery. Check publish status first, then confirm the trigger event genuinely matches what happened to the contact and in what order, then check filters at the trigger level, then re-entry settings, then branch logic and delay-step configuration, and use Enrollment History and Execution Logs to confirm exactly where a specific contact got stuck rather than guessing from the builder’s visual layout. Most of these are five-minute fixes once correctly identified. If workflows across an account are consistently built without clear re-entry and exit logic, that’s a broader pattern worth addressing at the build level, which the GoHighLevel agency setup guide covers in more depth alongside sub-account and snapshot architecture.

Related reading

FAQs

Why did my GoHighLevel workflow work once and then stop firing for new contacts?

This is almost always a re-entry setting, not a broken trigger. If re-entry is set to off (or limited to a certain number of times), a contact who already completed or started the workflow won't be evaluated again even if they satisfy the trigger a second time. Check the workflow's Settings tab for the re-entry option before assuming the trigger itself is broken.

How do I know if a contact was even evaluated by a GoHighLevel workflow trigger?

Open the workflow itself and check Enrollment History, which lists every contact who was evaluated against the trigger and whether they were enrolled or filtered out. This is a different view from the contact's own activity tab, and it's the correct place to start diagnosing, because it tells you whether the trigger fired at all before you spend time checking filters or actions.

Does a workflow in Draft status still run?

No. A Draft workflow will run when you manually trigger a test from inside the builder, which can make it look functional, but it will not fire from real trigger events on live contacts. The workflow has to be Published for live triggers to enroll contacts.

Why does a contact get filtered out of a workflow even though they meet the trigger condition?

Triggers and filters are evaluated separately, and if/else branches inside the workflow apply their own filter logic on top. A contact can correctly satisfy the trigger and still exit at the first branch if that branch checks a custom field or tag the contact doesn't actually have populated. Check branch conditions individually rather than assuming the trigger and the branches use the same logic.

My workflow has a delay step and nothing happens after it. What's wrong?

Check the delay step's configured duration and unit first; a delay set in days instead of minutes, or referencing a date field that's blank for that contact, will hold a contact indefinitely without any visible error. Also confirm the delay isn't set to resume at a specific time of day that hasn't occurred yet in the account's configured time zone.

Can an inactive or unassigned custom field cause a workflow to silently fail?

Yes. If a filter, branch condition, or personalization merge field references a custom field that's blank for a given contact, that step can behave unpredictably: filters route the contact to the wrong branch, and merge fields either render blank or break the message entirely. Auditing which custom fields are actually populated for the contacts entering the workflow is a standard part of troubleshooting.

How long should I wait before contacting GoHighLevel support about a workflow that isn't triggering?

Rule out the configuration items covered in this guide first: publish status, trigger event match, filters, re-entry, branch logic, and delay steps. Most non-firing workflows trace back to one of those. If a test contact still doesn't enroll after checking all of them, and Enrollment History shows no evaluation at all, that's a reasonable point to open a support ticket, since it may indicate a platform-side event delay or webhook issue.

What information should I include when escalating a workflow issue to GoHighLevel support?

Include the sub-account and workflow ID, the specific contact ID used for testing, the exact trigger event and the timestamp it should have fired, and screenshots of both the trigger configuration and the Enrollment History showing no evaluation. Specific, timestamped detail gets a workflow issue resolved faster than a general description of 'it's not working.'

Want a second opinion on your setup?

A free 30-minute call with an engineer. A written read on your current setup, whether or not you hire us.