All articles
WhatsApp Business

WhatsApp Chatbot Not Replying? Flow Trigger Fixes 2026

Chatbot ignoring messages? Most flow triggers match the whole message, not part of it — plus the open run that blocks every trigger. Diagnose each cause.

RichAutomate Editorial
11 min read 0 views
WhatsApp Chatbot Not Replying? Flow Trigger Fixes 2026

A WhatsApp chatbot that does not reply is almost never "down" — in most cases the message arrived, the webhook fired, and the trigger simply did not match. The single most common cause is that the keyword trigger compares the entire incoming message against the keyword, so a flow keyed on demo fires on demo and stays silent on I want a demo, Demo? and even demo. with a full stop.

The second most common cause has nothing to do with keywords at all: the contact already has an open flow run parked on a node that is waiting for a button tap, and an open run suppresses trigger evaluation entirely. This guide separates the two, then walks the rest of the failure classes in the order you should check them.

First, prove the message actually reached the bot

Three different systems have to succeed before a trigger is ever evaluated: Meta has to deliver the webhook, your app has to persist the inbound message, and the trigger job has to run. Diagnosing trigger logic while the webhook is broken wastes hours, so settle this first.

Check, in this order:

  • Does an inbound row exist for that contact at that timestamp? No row means this is a webhook problem, not a bot problem — the trigger code never executed.
  • Is the number subscribed to your app? A WABA that was never subscribed receives messages in the WhatsApp app but delivers no webhooks to you.
  • Is the queue worker alive? Trigger evaluation is normally dispatched as a background job. If the worker is stopped or draining a different queue than the one the job was pushed to, inbound rows accumulate and nothing ever replies. This is the same class of failure that leaves a campaign stuck at QUEUED or PROCESSING.

Only when an inbound row exists and the worker is consuming should you start blaming the trigger.

Keyword triggers usually match the whole message, not part of it

This is the finding that resolves most "my bot ignores customers" tickets. Trigger matchers are commonly written as a normalised equality check — lowercase both sides, trim whitespace, compare. Our own engine does exactly this, and so do many others.

The practical consequence, for a flow with the keyword demo:

Customer typesFires?Why
demoYesExact match after lowercasing
DemoYesCase is normalised on both sides
demo YesWhitespace is trimmed
demo.NoPunctuation is not stripped
I want a demoNoWhole-message equality, not substring
Demo pleaseNoSame reason

Real customers type sentences. If your keyword list contains only bare words, a large share of genuinely interested people will hit silence. Two fixes, in order of preference:

  1. Add the sentences to the keyword list. Unglamorous but immediate — enumerate the ten phrasings your customers actually use, including the punctuated variants.
  2. Add a catch-all flow. A trigger type of any matches every inbound message, which guarantees the customer gets something rather than nothing. Read the ordering warning in the next section before you do this, because a catch-all placed wrongly disables every other flow you own.

Do not assume your builder does fuzzy matching, stemming or intent detection unless its documentation says so explicitly. Test it: send hello there to a flow keyed on hello and watch what happens.

Only one flow ever fires — and it is the first one found

Trigger evaluation typically loops over active flows and stops at the first match. That has two consequences that surprise people.

A catch-all swallows everything behind it. If a flow with trigger type any is evaluated before your keyword flows, it matches every message and returns, and no keyword flow will ever run again. The keyword flows are not broken; they are unreachable. If you added a fallback flow last week and your specific flows went quiet at the same time, this is your answer.

Evaluation order is often not something you control. Where there is no explicit priority field, order comes from whatever the database returns — in practice creation order. Duplicating a flow to test a change can therefore silently change which of the two wins. Keep exactly one catch-all, and make sure it is the newest flow you own, not the oldest.

An open flow run blocks every trigger

This is the failure that looks most like an outage, because the bot goes silent for one specific customer while working perfectly for everyone else.

The sequence: a contact reaches a node that waits for input — a button node, a list node, a data-collection node. The run stays open at that node. When the next message arrives, the engine first asks "is there an open run, and does its current node know how to handle this?" Only if the answer is no does it fall through to trigger evaluation.

So a contact parked at a button node who never taps a button is, from the bot's point of view, still mid-conversation — possibly for months. Three details make this worse than it sounds:

  • Waiting nodes commonly have no timeout. Many engines, ours included, park indefinitely at a button node with no expiry and no nudge. Nothing reclaims that run on a schedule.
  • Typed text at a button node is not a button reply. Button handling reads the interactive payload Meta sends when a button is tapped. Free text carries no such payload, so it does not advance the node.
  • That text then falls through to trigger evaluation. If you have a catch-all, the flow restarts from the top — which is exactly why some bots answer every typed reply with the welcome message again, in a loop, while the customer grows steadily more annoyed.

Fixes worth building: give every waiting node a text fallback edge so typed input advances rather than restarting; add a scheduled sweep that closes runs idle beyond a sensible window; and make sure your buttons are actually tappable — see reply buttons, list messages and interactive templates for the payload shapes involved.

Status values are case-sensitive and there are two of them

A quiet, infuriating class of bug: the flow record and the flow run record often use different casing conventions for their status column — a flow may be looked up as ACTIVE while a run is looked up as active. Nothing enforces this at the database level, so a flow written by an import script, a seeder or a direct SQL update with the wrong case is invisible to trigger evaluation while looking perfectly enabled in the dashboard.

Stop overpaying on WhatsApp

Get a 1-minute BSP audit on WhatsApp

Drop your WhatsApp number — we line-item your current invoice against Meta India rates in under 60 seconds. India-hosted, DPDP-compliant.

DPDP-compliant · India-hosted · 1-min reply

If a flow shows as active in the UI and still never fires, read the raw column value before anything else. It is a five-second check that has resolved more than one multi-hour investigation.

The contact must belong to the same tenant as the flow

Flow lookup is tenant-scoped: the engine reads the contact's tenant and fetches active flows for that tenant only. A contact row created against the wrong tenant — by an import, a stale API key, or a second account someone forgot about — sees zero flows and therefore never triggers, no matter how many active flows exist elsewhere in the system.

This one is easy to spot once suspected: count active flows for the contact's tenant, not for your logged-in tenant. If the answer is zero, you have found it. The same class of mismatch causes duplicate-account confusion across the whole product, so it is worth resolving properly rather than by moving one contact.

Editing a live flow can kill the runs already inside it

Flows are usually stored as a JSON graph, and a run remembers only the id of the node it is parked on. Delete or replace that node while a run is parked there, and the next message from that contact resolves to a node that no longer exists. The typical handling is to log an error and mark the run failed.

The customer's experience is that the bot answered yesterday and is silent today, with no visible cause. Two habits avoid it:

  • Never delete nodes from a live flow. Add the new branch, point the edges at it, and leave the old node orphaned but present until the in-flight runs have drained.
  • Version by cloning. Build the change as a new flow, switch the trigger over, and retire the old flow once its runs are done.

Related trap: loop-detection. Engines that guard against infinite loops by tracking visited nodes within one execution will abort a run that legitimately revisits a node — a "return to main menu" edge is the usual victim. If your menu loop dies on the second pass, this is why, and the fix is a distinct node per pass rather than a true cycle.

Multi-number tenants: the bot may reply from the wrong number

When a flow sends a message, it needs a WhatsApp account to send from. A common implementation picks the first account belonging to the flow's tenant. With one number that is correct and invisible. With two numbers it is a coin toss decided by row order.

The symptom is not silence — it is a reply that arrives from a number the customer never wrote to, which breaks the thread, looks like spam, and often gets reported. If you run more than one number under a single tenant, verify explicitly which account your flow engine selects before you scale volume on it.

Trigger evaluation usually gets one attempt

Trigger jobs are frequently configured to run once, with no retry. The reasoning is sound — retrying a trigger risks starting the same conversation twice, which is worse than missing it. The consequence is that a transient failure during evaluation, a database blip or a deadlock, drops that trigger permanently. There is no dead-letter replay for a conversation that never began.

You will not see this in the bot's logs as a customer complaint, because the customer simply got no reply and moved on. The only way to find it is to compare inbound message counts against run-created counts over the same window and investigate the gap.

A closed run does not mean a finished conversation

When a new flow starts for a contact, engines commonly close any open runs for that contact first — and the status they write is usually completed. An abandoned conversation and a successful one therefore end up looking identical in the data.

If you report on flow completion rates, this inflates them, in the same way that a campaign marked COMPLETED says nothing about whether anyone received it. Distinguish the two states if the number matters to you: record whether the run reached a terminal node, not merely whether it stopped being open.

The diagnostic order that settles it fastest

Work down this list. Each step rules out a whole class, so do not skip ahead.

  1. Is there an inbound row for that message? No → webhook or subscription problem, stop here.
  2. Is the queue worker consuming the queue the trigger job is dispatched to? No → fix the worker.
  3. Does the contact have an open run? Yes → it is parked, not broken. Find its current node.
  4. Read the flow's raw status value. Wrong case or wrong tenant → invisible to evaluation.
  5. Is there a catch-all flow evaluated before this one? Yes → your keyword flow is unreachable.
  6. Test the exact string the customer sent against the keyword list, character for character, punctuation included.
  7. Confirm the parked node still exists in the current flow JSON.

Six of these seven are configuration or state, not code. That ratio is the real lesson: a chatbot that stops replying is far more often a flow that cannot be reached than a flow that is broken.

What to build before you scale a bot

  • A text fallback on every waiting node, so typed input always advances rather than restarting or dead-ending.
  • An idle-run sweep that closes runs parked past a sensible window, so one unanswered button does not silence a contact permanently.
  • Exactly one catch-all, evaluated last, that either answers usefully or hands off to a human — see bot-to-human handoff for what a good escalation looks like.
  • An inbound-versus-run-started reconciliation, run daily. The gap is your silent-failure count, and without it you will never know the number.
  • A canary contact you message after every flow edit. Editing live graphs is the most common way to break a bot that was working.

Further reading

A bot that tells you why it stayed quiet

Most of the failures above are invisible by design — the engine did exactly what it was told and said nothing. RichAutomate exposes run state, current node and trigger evaluation per contact, so "the bot ignored me" becomes a question with an answer instead of a guess. See how it works.

Ready to ship this?

Get the full migration playbook on WhatsApp

A founder-led 1-minute reply with the migration steps, template approval timeline, and a 14-day pilot offer. DPDP-compliant. India-hosted. No spam.

DPDP-compliant · India-hosted · 1-min reply
Tagged
WhatsApp Business APIChatbotFlowsTroubleshootingIndia
Written by
RichAutomate Editorial
Editorial team at RichAutomate. We build the WhatsApp Business automation platform Indian D2C brands, fintechs, and agencies use to ship campaigns and flows on the official Meta Cloud API.
FAQ

Frequently asked questions

Why does my WhatsApp chatbot not reply to some messages?
The most common reason is that keyword triggers compare the entire incoming message against the keyword rather than searching within it. A flow keyed on 'demo' fires on 'demo' but not on 'I want a demo' or even 'demo.' with a full stop. The second most common reason is that the contact already has an open flow run parked on a node waiting for input, and an open run suppresses trigger evaluation entirely.
My WhatsApp flow is active but never triggers. What should I check?
Check in this order: that an inbound message row actually exists (no row means a webhook problem, not a bot problem); that the queue worker is consuming the queue the trigger job is dispatched to; that the contact has no open flow run; that the flow's raw status column value matches the case the lookup expects; that the contact belongs to the same tenant as the flow; and that no catch-all flow is evaluated before yours.
Why does my WhatsApp bot keep sending the welcome message over and over?
The contact is parked at a button or list node and is typing text instead of tapping. Typed text carries no interactive payload, so it does not advance the node; it falls through to trigger evaluation instead, where a catch-all flow matches it and restarts the flow from the top. Add a text fallback edge on every waiting node so typed input advances rather than restarting.
Can adding a fallback flow break my existing WhatsApp chatbot flows?
Yes. Trigger evaluation usually stops at the first matching flow, and a catch-all trigger matches every message. If the catch-all is evaluated before your keyword flows, those flows become unreachable — they are not broken, just never reached. Keep exactly one catch-all and make sure evaluation order puts it last.
Why did my WhatsApp chatbot stop working after I edited the flow?
A flow run stores only the id of the node it is parked on. Deleting or replacing that node while runs are parked there means the next message resolves to a node that no longer exists, and the run is typically marked failed. Never delete nodes from a live flow — add the new branch, repoint the edges, and leave the old node orphaned until in-flight runs drain, or clone the flow as a new version.
Does a completed WhatsApp flow run mean the conversation finished successfully?
Not necessarily. When a new flow starts for a contact, engines commonly close any open runs first and write the status as completed. An abandoned conversation and a successful one therefore look identical. To measure completion honestly, record whether the run reached a terminal node rather than whether it simply stopped being open.
RichAutomate · WhatsApp BSP for India 2026

Ship WhatsApp campaigns + flows on a transparent, compliance-ready BSP.

₹0 platform fee. DPDP audit log included. Visual flow builder. Multi-tenant from day one.

Start free trial
Want this for your brand?

Get a free 24-hour BSP audit

Send us your last invoice. We line-item it against Meta's published rates and benchmark against three alternatives.

Limited Spots Available

Get a Free
Automation Audit

Stop leaving revenue on the table. Get a custom roadmap to automate your growth.

Secure & Confidential