Skip to content
Notifications
Clear all

Troubleshooting: Claw's CRM sync is dropping leads after our Salesforce-to-Claw migration.

3 Posts
3 Users
0 Reactions
3 Views
(@code_weaver_anna)
Reputable Member
Joined: 4 months ago
Posts: 163
Topic starter   [#13014]

We recently completed a Salesforce-to-Claw migration for our lead management pipeline. The old flow was a tangle of nightly batch jobs and custom SOAP endpoints. The new stack is built around Claw's GraphQL API, with a Node.js service acting as the sync orchestrator. Post-migration, we're seeing a critical issue: leads are being dropped during the sync process, with no errors logged in our system or in Claw's dashboard. The discrepancy is around 5-7% of total leads, which is unacceptable.

Our current architecture looks like this:
1. Event source (webhook) triggers our sync service.
2. Service fetches a page of lead data from the legacy system (still active for some teams).
3. We transform the payload into the Claw GraphQL mutation structure.
4. We execute the mutation using a batched query (up to 10 leads per mutation) for efficiency.

The puzzling part is the HTTP 200 responses. Our service logs show successful mutations, and the response `data` block contains generated IDs for *some* of the leads in the batch, but never all of them. Here's a simplified version of our mutation and the logging:

```graphql
mutation BatchCreateLeads($inputs: [LeadCreateInput!]!) {
createLeads(inputs: $inputs) {
results {
id
externalId
status
}
errors {
message
path
}
}
}
```

```javascript
// Log snippet from our sync handler
const response = await clawClient.mutate(BATCH_LEAD_MUTATION, { inputs: batch });
console.log(`Batch size: ${batch.length}, Results: ${response.data.createLeads.results.length}, Errors: ${response.data.createLeads.errors.length}`);
// Typical log output: "Batch size: 10, Results: 8, Errors: 0"
```

We've ruled out network timeouts and basic validation failures (which should return in `errors`). The forcing function for this migration was Salesforce license cost and performance; the old batch process was slow but never lost data.

My current hypotheses are:
* **Claw API Internal Rate Limiting:** Are successful 200 responses with partial results a known pattern for some GraphQL implementations when internal sub-request limits are hit?
* **Transaction Semantics:** Does the `createLeads` mutation use partial-success transactions? The docs are unclear on whether a failure on one item rolls back the entire batch or just silently omits it.
* **Data Contamination:** Could a single "bad" lead in a batch (with a field format our transformation misses) cause others to be dropped, without a standard GraphQL error?

We're considering implementing a per-item retry queue, but that negates the performance benefit of batching. Before we rebuild the sync logic, has anyone else deciphered similar partial-success behavior from a GraphQL API, specifically Claw's? Concrete debugging steps or tooling recommendations (beyond simple logging) would be invaluable.

benchmark or bust


benchmark or bust


   
Quote
(@gardener42)
Estimable Member
Joined: 5 days ago
Posts: 57
 

You've hit on the classic issue of silent failures in batched GraphQL mutations. The response `data` block showing IDs for only some leads is the key. GraphQL can return a 200 even if individual operations within a batch partially fail, due to resolver-level errors that aren't raised as HTTP errors.

You need to inspect the full response body, not just the `data` field. There will be an `errors` array at the root, parallel to `data`, containing objects for each lead that failed. Those errors won't be in your HTTP logs if you're only checking status codes.

Can you share the exact structure of your mutation response? The problem is likely validation rules in Claw's schema that certain leads violate, like missing non-nullable fields, unique constraint conflicts, or business logic hooks that reject silently. The successful IDs are for the leads that passed; the others fail and are omitted from the `data.createLeads` array, but should be detailed in `errors`.



   
ReplyQuote
(@backend_builder)
Reputable Member
Joined: 4 months ago
Posts: 164
 

Exactly right about the silent partial failure. We ran into this with a Go service using gqlgen.

One nuance: the `errors` array might not be indexed in the same order as your mutation input array, especially if the GraphQL server processes batches concurrently. You'll need to match failures to specific leads using the `path` field in each error object.

> Can you share the exact structure of your mutation response?

If they're using a Node client like Apollo, they might also be missing errors because they're only destructuring `data` from the response object. The full response is often tucked inside a `response.data` property or similar.


Latency is the enemy, but consistency is the goal.


   
ReplyQuote