Why Your Clay Push to Salesforce Keeps Failing

A 200 record job came back with 127 failures, and Clay said every row was fine.

Tim Burnham, Founder

Tim Burnham

Founder

September 26, 2026

Clay told us the rows succeeded.

Salesforce had nothing.

Not an error, not a partial write. The table was green and the CRM was empty, which is the worst version of this problem because there's nothing to go read.

So we went looking, and it turned out we were asking the wrong system. Clay had done its job. It handed the records to Salesforce, and Salesforce quietly threw most of them away.

Here's what that looked like:

  • 127 of 200 records failed on one job.
  • 173 contact updates failed on another.
  • All 132 account records failed on a third.
  • 200 failures out of 2,900 on a bigger run.

And once we fixed it, a push of ~180 contacts landed clean.

The first thing to know: Clay is not lying to you

A Clay row action reports whether the request worked. Salesforce accepting the record is a separate question, and it gets answered somewhere else.

Worse, Clay Audiences would update perfectly while the Salesforce write failed. So the record looked right in two places and was missing from the only one that mattered.

Where the actual error lives

Two places, in this order:

  1. Salesforce → Bulk Data Jobs. This is where the failed rows are, with a reason attached. Start here. It's the difference between "something's broken" and "this field is too long".
  2. Developer Console logs. When the bulk job reason is too vague, this gives you Salesforce's specific rejection.

Then, before you re-run 2,000 records, push two. Pick one record you think is fine and one you think is the problem. It takes a minute and it tells you whether you actually found the cause or just found a cause.

The five things that were actually wrong

1. A field was over its character limit. The personal property account number is capped at 30 characters in their org. Anything longer takes the whole record down, not just the field.

2. A currency field was getting text. The tax bill amount had to be a pure number. We were sending it formatted, with the explanation attached, which reads beautifully to a human and is a type error to Salesforce. The narrative moved to Clay Notes and the field got the raw number.

3. An AI step was inventing picklist values. Industry is a dropdown. Salesforce only accepts values that already exist in it, and an AI asked to "fill in the industry" will happily write something sensible that isn't on the list. We had to go get the real list and map to it.

4. New accounts had no owner ID. Records arriving without one failed. The ~180 contact push that finally worked was exactly the set that had owner IDs, which is how we knew.

5. One field was read-only and we didn't know. Prospect status doesn't sync to contacts because it's inherited from the account. Nothing we did at the contact level was ever going to stick.

Four of those five are the same mistake: we sent a value that was right for a person to read and wrong for the field to hold.

The bigger one: check if a sync already exists

This is the part I'd want to know before building anything.

Their Salesforce already two-way synced with Clay Audiences. So writing the Audiences record was already reaching the CRM. We built a direct Salesforce write on top of that, which meant two writers on one field, on two different paths, drifting apart.

Clay won't warn you. The action catalog shows you update-object whether or not a sync exists, because it has no idea.

So ask the client first. It's their setup and you can't see it from inside Clay. Use the direct write when there's no sync, or when you need a field the sync doesn't carry. Otherwise write the Audiences record and let the sync do its job.

(We got this backwards, then took the direct write back out.)

As a bonus: this is all free

Every Salesforce action in Clay is Bring Your Own Account. Zero Clay credits. Reads and writes both.

That changes what's worth doing. A full GROUP BY census of a messy field costs nothing, so there's no reason to guess at what's in a field or ask the client to export it:

SELECT Workflow__c, COUNT(Id) total
FROM Contact
WHERE Workflow__c != null
GROUP BY Workflow__c
ORDER BY COUNT(Id) DESC

And you can pull every writable field with its real API name, type, and the full picklist options, without a describe call. Which would have caught problem 3 before we ever wrote a row.

One limit worth knowing: Clay caps Salesforce SOQL queries at 25 a day. Once you hit it, things stop quietly, which by now you'll recognise as the theme.

What I want to know

If you've pushed to Salesforce from Clay at any scale, I want to hear which field broke it for you. I suspect the list of five is really a list of twenty and I've only met a few of them.

Where this fits

Growth Systems

See the service