The No Code Tools That Almost Broke My Client’s CRM
1. Figuring out what Zapier actually sends to Airtable
I set up what looked like a dead-simple Zap: New Calendly event → Create row in Airtable. I used the main Airtable Zapier integration module, filled out the base and table, mapped each field, tested it, got green checks, and pushed it live. Cool. Until my client called two days later saying half their rows were blank except for the timestamp.
The Calendly trigger was sending the right data — I verified it in the Zapier history. But somehow Airtable was still getting nothing for name, email, or notes. After digging, I realized: if you map a field using a dynamic placeholder (e.g., “Invitee Email”) and that placeholder doesn’t exist in a specific event payload, Zapier doesn’t throw an error — it just sends blank data to Airtable without complaint.
And it gets worse. If the field used to exist in previous test payloads, Zapier will still show it in the dropdown and suggest it’s available for future inputs. But Calendly sometimes omits fields entirely (like notes, if the person didn’t write one), so your structure breaks silently. You’d need a conditional step to check for field presence — or pad every single field with {{Invitee Email | default:”Missing”}}, which Zapier still doesn’t support natively.
Once I added a filter step above Airtable to block entries with missing email addresses, the issue stopped. But of course, that introduced another trap I didn’t see coming until a few dozen entries later.
2. When Notion API throttled Zapier mid-import and never told me
I was importing around five hundred Google Sheet rows into Notion using Zapier. Seemed fine. Zapier was looping through each row using a Google Sheets “New Row” loop trigger — imperfect, but it functioned — and creating a matching Notion database item.
What I didn’t know: Notion has an undocumented throttle window where it will accept incoming requests but not process them fully. If you blast too many requests across a short time span, Zapier sees them as “Successfully sent” (because technically, the HTTP request went through) but inside Notion… crickets. No error, no failed item, no row. Just dropoff.
I only caught this because I realized the row counts were out of sync. 482 Google Sheet rows. 391 Notion items. No failures in Zapier.
Real kicker? Zapier logs marked every one as completed. Not even a warning in the task log. I had to rebuild this using a delay plus a Make scenario that staggered API sends with a 3-second wait. That actually worked. I also learned that Notion’s rate limit is more bursty than linear. You can shoot ten items in ten seconds every so often, but not fifty in a row. Not reliably.
This edge case doesn’t show up in any Notion or Zapier documentation. Closest thing I found was someone on a GitHub issue speculating the API “gets warm” inconsistently if your requests span multiple databases. Which mine did. Great.
3. How Airtable Automations deadlock if you copy linked records too fast
I built a sales tracker in Airtable where every time a new deal record was marked “Closed Won,” an automation would clone the record into a Projects table — completing some linked record fields along the way. Took 15 minutes to assemble. And it worked… until it didn’t.
Copying over text fields? Instant. Select lists? Also fine. But when I added a linked record field to grab the associated client from the original row? The automation failed dead quiet. The “Add record” step completed, but the linked field was blank 20-30% of the time, and I couldn’t reproduce why.
Turns out Airtable has a race condition where newly created linked records aren’t always fully resolvable immediately in a subsequent step — especially if you’re writing them back into another base or table that’s already in sync with external tools. It’s not documented, but I hit it five times in a row before inserting a Wait ~1s script block and suddenly everything acted normal again.
“You can’t reference a custom field that was just created 200ms ago — even if Zapier’s UI shows it as tested.”
Also: if the linked record was created in a previous automation (not manually), it’s even more likely to fail. It seems like Airtable doesn’t full-sync automation-created records into the ‘visible layer’ fast enough if a second automation tries to access them immediately.
4. Coda buttons only fire once per session via Zapier webhook
This one took me a week. I was helping a team automate content approvals via Coda. The writer would hit a button in the doc → webhook → Zapier checks the HubSpot record → updates Slack → sets a flag back in Coda to mark it approved.
Worked great for the first run of the day. But if a second submission happened? Nothing. No Zap ran. No log. Button did nothing after the first attempt per browser tab. Found out later: Coda buttons using “Call webhook” action don’t reliably re-fire unless the backend Zapier URL is toggled somehow — even if you refresh the page.
I finally got it working by sending the webhook to a Make webhook that then relayed it to Zapier, which Zwifted the payload and forced a refresh cycle. Ugly, but functional. Even Coda support was like, “Yeah we’ve seen that. It’s kind of cached.”
I added a random query string to the webhook URL using a hidden field in Coda (like ?trigger={{Now()}}) — that finally forced multiple button calls to be unique per press.
Five things I wish I had known sooner:
- The webhook preview in Coda lies if you’re logged in as a Maker
- Zapier logs a webhook even if it didn’t parse the payload
- If your webhook response doesn’t include a 200, Coda retries it
- Coda caches responses to the same exact URL
- You can only run 1,000 buttons/day on Coda Free
- Buttons silently fail if the target webhook URL exceeds 2kb
5. Make HTTP module needed double-encoding for Google Calendar events
I was scripting Google Calendar event creation with Make. Thought it’d be simple. Set the title, attendees, datetime, description — done. Nope. Google kept throwing “Bad Request / malformed input” errors specifically tied to the location field.
It wasn’t the field name, or the format — it was literal character encoding. Make passes JSON payloads almost-perfectly, but sometimes — and only in custom HTTP modules — it encodes special characters twice. And Google’s Calendar API expects only standard UTF-8.
So a title like “All Hands — Q3 Review” got encoded to “All Hands Q3 Review”. Google parsed that fine. But when I added a link in the location field (e.g. “https://zoom.us/j/123”) — boom, error. Took three rounds of debugging and trying token replacement filters to realize that Make was percent-encoding some characters before I even touched them.
The fix was to inject the payload directly as a raw string with double brackets and bypass Make’s concatenator. So instead of passing an Object → JSON, I just used:
{“location”: “{{text}}”}
This forced Make to leave it alone. Worked instantly after that. But no docs mention this — and Make’s Calendar app module doesn’t even support setting custom location fields manually unless you go full HTTP module anyway.
6. Cloudflare pages threw 403s during automation but loaded in browser
Client was hosting their lead-gen form on a Cloudflare Pages static site. Lookup table in Airtable, trigger in Zapier, form submission embeds into the workflow. But Zapier’s webhook received a 403 — no response body — while the same URL worked in any browser, any time.
It turned out to be a Cloudflare default security policy (WAF) that blocks “non-browser user agents” unless you add a bypass. Nothing in the dashboard screamed “block automation tools.” I only found it by running the webhook using curl and catching the returned headers that said cf-ray: blocked
.
There’s a random checkbox under “Bots” in Cloudflare’s settings called “Verify additional HTTP traffic” — disabling it immediately fixed the issue. But I still have no idea why curl worked and Zapier didn’t, until someone in the group chat suggested the User-Agent string was too generic.
Switched the webhook call to use a relay URL with a custom header, and that got through. Felt very much like a workaround for something that shouldn’t be happening in the first place.
7. When Slack delays message delivery and ruins conditional Zaps
I had a Slack → Gmail alert running through Zapier. Every time our #vendors channel got a message with the word “invoice” in it, the Zap skimmed it, checked the context, and forwarded it to the finance queue. That was the plan, at least.
But every few days, it missed messages completely — even if they matched perfectly. Checked the Zapier logs — nothing. Slack history? Full message visible. What tripped me up was Slack’s silent delay when unfurling links or rendering attachments. For text-based messages with no links, delivery to Zapier was instant. For anything with a PDF upload or link preview? Slack held the final event until processes finished. But Zapier’s trigger fired as soon as the message object appeared — before the full JSON body had final values.
This means conditional logic built on “has_attachment = true” sometimes evaluated falsely if the attachment hadn’t populated yet. Disabling link previews helped. For longer messages that needed unfurling, I added a 30-second Schedule delay into the path, then re-pulled the message ID using the Slack API before evaluating the condition.
Feels absurd to say out loud, but yes: Slack sometimes fakes a message state for 10 to 30 seconds before finalizing it, and Zapier reacts too early if you’re not careful.