AI Automation

Your Automation Is Running Fine and Still Lying to You: Build a Daily Reconciliation Check

Written by
Pravin Kumar
Published on
Sep 22, 2026

How do I know the two systems my automation connects still agree with each other?

You do not know until you check. Build a small scheduled job that counts and compares the records on both sides every day, then alerts you when the two numbers diverge. Monitoring catches automations that fail. Reconciliation catches automations that succeed and are quietly wrong.

Almost every automation I have shipped connects two systems that each believe they are the source of truth. Airtable and a website. HubSpot and a spreadsheet. A form and a CRM. On day one they match. Nobody checks again until something visible breaks, which is usually weeks later and usually in front of a customer.

This article is about the cheapest insurance I know for that problem, which is a daily reconciliation check that takes an afternoon to build and almost nothing to run.

What is a reconciliation check, and how is it different from monitoring?

Monitoring watches the automation. Reconciliation watches the outcome. A monitor asks whether the run completed without an error. A reconciliation check asks whether the two systems now hold the same set of records, and it does that independently of whether any run reported a problem.

The distinction matters because the failures that hurt most are the ones that never raise an error. A record gets created with an empty field. A filter silently excludes a category after someone renames it. A webhook fires twice and you end up with a duplicate nobody notices. Every run in the history shows green.

I already wrote about the failure class where nothing throws an error at all in monitoring silent automation failures. Reconciliation is the specific technique I now reach for first, because it does not depend on the automation being honest about itself.

Why do two synced systems drift even when nothing errors?

They drift because sync tools move changes, not truth. A sync replays what it saw happen. If it did not see something happen, because of a paused connection, a permissions change, a renamed field, or a record edited outside the tool, nothing is replayed and nothing complains. The gap is invisible by design.

The second cause is humans. Someone edits a record directly in the destination system because it was faster. That edit is now out of band. Depending on the sync direction, it either gets overwritten later or it survives and makes the destination permanently different from the source. Neither outcome produces an alert.

The third cause is the boundary conditions nobody tested. Records created exactly at a scheduled run, records deleted during a run, records that fail validation on one side and pass on the other. I covered the specific patterns I have hit on one stack in Airtable to Webflow CMS sync failure modes, and almost all of them show up as drift rather than as an error.

What should the daily check actually compare?

Start with three comparisons: total record count on each side, the count of records created in the last twenty four hours on each side, and a spot check on the fields that matter most. If those three agree, you are almost always fine. If any disagrees, you get a message with the numbers in it.

Counts are the cheapest signal and they catch most real problems. If the source has more records than the destination, something is not arriving. If the destination has more, something is arriving twice or something is not being cleaned up. Either way you learn about it while the gap is small enough to fix by hand.

The field spot check is the second layer. Pick the two or three fields that would embarrass you if they were wrong, usually a status, a price, or an email address, and compare them on a sample of recent records. You do not need to check everything. You need to check the things that cause a refund or an apology.

How do you build this without building a second product?

Keep it to one scheduled run, two reads, one comparison, and one message. If the check needs its own database, its own dashboard, or its own retry logic, you have overbuilt it. The check should be simpler than the automation it watches, or it becomes the next thing that breaks silently.

My rule is that a reconciliation check gets a single execution path and no state. It reads both sides fresh each time, compares, and either says nothing or says exactly what differs. No history, no trend charts, no storage. If I want history I read the messages, because the messages are the log.

The other rule is that the check must not use the same connection as the automation. If the automation's credential expires, a check that shares that credential fails in the same breath and tells you nothing. Separate credentials mean the check can still report that the automation has gone quiet.

What does n8n give you for this specific job?

n8n documents an error workflow that you set per workflow in Workflow Settings, and it runs whenever an execution fails. n8n's docs give the example of sending email or Slack alerts from it. That error workflow has to start with the Error Trigger node, and the same one can be reused across many workflows.

The part that matters most for reconciliation is the Stop And Error node. n8n's documentation describes it as a way to force an execution to fail under your chosen circumstances and trigger the error workflow. That is exactly the shape a reconciliation check wants. Read both sides, compare, and deliberately fail the run when the numbers do not match, so the alerting you already built fires for free.

n8n also notes that the data sent to an error workflow includes an execution.retryOf value that is only present when the execution is a retry of a failed execution. That is a small detail with a practical use: it lets an alert distinguish a first failure from a repeat, which is the difference between a message you read later and a message you act on now.

What if you are on Make or Zapier instead?

Make documents a whole error handling section covering error handlers, exponential backoff, and a Throw directive, which gives you the same deliberate-failure pattern. Zapier documents replaying failed Zap runs. Check each vendor's own docs for what your plan allows, because that is the part that changes without warning.

The pattern survives the platform change. Read both sides, compare, throw on mismatch, route the throw to a human. Whether the throw is called Stop And Error, Throw, or a filter that leads to a notification step matters less than the fact that the comparison exists and runs on a schedule you did not have to remember.

For the Kismet Health work, where HubSpot is fed through Zapier, the useful mental model was the same. The CRM is the destination that matters, so the question worth asking daily is whether what reached the CRM matches what left the form, not whether the Zap ran.

Where should the alert land, and who is supposed to read it?

One channel, one human, and a message that contains the numbers rather than a link to go find them. If the alert needs someone to log in somewhere to understand it, it will be ignored by the second week. Silence should mean healthy, and any message at all should mean look now.

I have made the mistake of routing reconciliation alerts to a busy shared channel. They get absorbed into the noise and everyone assumes someone else has it. A reconciliation alert should go somewhere quiet, ideally somewhere that receives nothing else, so that its arrival is itself the signal.

The message format I settled on is boring on purpose. Source count, destination count, difference, and the three most recent records that exist on one side and not the other. That is enough to decide in ten seconds whether this is a timing artifact or a real break.

Does this actually matter at small scale?

At small scale you can eyeball it, so the check buys you less. Its value grows with volume and with how long the automation has been running unattended. The automations I would never run without reconciliation are the ones where nobody looks at the underlying data for weeks at a time.

The Ajust work is the clearest example in my own practice. That stack runs on Airtable synced through WhaleSync, and it has delivered more than 25,000 cases, helped more than 400,000 people, and saved more than 50,000 hours. At that volume a silent gap is not a tidy little bug. It is a set of real people whose records did not arrive, and nobody involved would have found out from a green run history.

If your automation touches ten records a week and you open the system every day, skip the check and spend the afternoon elsewhere. Honesty about that is part of the job. Most automation advice assumes everything deserves production hardening, and most things do not.

What should you do next?

Pick the automation whose failure would cost you the most, and write down the one number on each side that should always match. Build a scheduled job that compares those two numbers and messages you when they differ. Ship that before you build anything cleverer.

The thing I would tell my earlier self is that reconciliation is not a maturity milestone you graduate to. It is the first thing to build after the automation works, because the window between working and quietly wrong is shorter than anyone expects. I described the sync-specific version of this habit in keeping Airtable and a website in sync with WhaleSync.

If you have an automation running in production and you are not sure whether the two ends still agree, tell me what it connects and I will tell you what I would compare first. Let's chat.

Get found, cited and the back office automated

Let's make your site the source AI engines quote and wire up the systems behind it.

Contact

Let's get your website found and cited by AI

Tell me what you're working on, whether AI search is skipping your product, your back office is buried in manual work, or you need a build that does both.

Got it, thanks. I read every message personally and reply within 1-2 business days.
Oops! Something went wrong while submitting the form.