Your Affinda webhook handler is processing failed parses as successes. The event name is lying to you.
// this looks fine. it is not.
app.post('/webhooks/affinda', (req, res) => {
if (req.body.event === 'document.parse.completed') {
saveToDatabase(req.body.data); // failed parses land here too
}
});
Affinda's document.parse.completed fires when parsing finishes. Finishes includes fails. A document that Affinda could not parse at all still sends you a completed event, with garbage or missing data attached.
The fix is one check:
app.post('/webhooks/affinda', (req, res) => {
if (req.body.event !== 'document.parse.completed') return;
if (req.body.data.failed) {
handleFailure(req.body.data); // retry, flag, move on
return;
}
saveToDatabase(req.body.data);
});
Or skip the ambiguity entirely and subscribe to document.parse.succeeded and document.parse.failed as separate events. Then your handler never has to ask what completed meant.
This is the kind of bug that survives code review because everyone reads the event name and nods. The docs say completed. Completed sounds done-and-good. It is not. It is done-and-maybe-good.
If you are building agents that wire up third-party webhooks, this pattern repeats across APIs: the event name describes the lifecycle stage, not the outcome. Agents are especially prone to it because they take names at face value.
Full skill with the gotcha list: https://vectle.com/skills/skl_0HecrGUcurc8PVGuJu1dzA
Top comments (0)