Ce qui se passe
Dans le Workflow SDK de Vercel, start() accepte maintenant une option experimental_hook : il admet le run et
réserve un hook en une seule étape atomique. Un démarrage en double échoue proprement. L'ancien motif enchaînait
getHookByToken() puis start() ; entre la recherche et le démarrage, une course documentée laissait deux requêtes
simultanées lancer chacune un run (webhook rejoué, double clic).
Le mécanisme
Le jeton du hook est la clé d'idempotence, et il vient de votre domaine : un identifiant de commande, de facture,
d'import ou de requête. Un seul run le possède. Un second start() avec le même jeton lève HookConflictError, qui
porte le conflictingRunId du propriétaire, et ne devient jamais un run.
try {
const run = await start(processOrder, [orderId, note], {
experimental_hook: { token: `order:${orderId}` },
});
return Response.json({ runId: run.runId, started: true });
} catch (error) {
if (!HookConflictError.is(error)) throw error;
// Le doublon envoie sa charge au run qui possède déjà le jeton
const hook = await resumeHook(`order:${orderId}`, { note });
return Response.json({ runId: hook.runId, started: false });
}Le hook réservé existe dès l'admission : resumeHook fonctionne avant que le run n'ait commencé à s'exécuter, et les
charges arrivées trop tôt sont mises en tampon puis livrées dans l'ordre. Dans le workflow, createHook({ token }) avec
le même jeton se lie au hook déjà réservé : aucun conflit possible, rien de nouveau enregistré, aucune étape ajoutée.
Le jeton seul garantit l'idempotence : si le workflow n'ouvre jamais le hook, il n'aura servi que de clé, et le run se
termine normalement.
Les limites
L'option porte le préfixe experimental_ : son interface peut encore changer. Pour qu'un doublon tardif soit aussi
refusé, experimental_minRetention garde le jeton indisponible après la fin du run, durée comptée depuis le start().
Comment s'y prendre
- Passer à
workflow5.4.0. - Remplacer vos paires
getHookByToken()puisstart()par un seulstart()avecexperimental_hook. - Choisir le jeton dans votre domaine : un identifiant aléatoire ne reconnaîtrait pas le doublon.
Source : changelog Vercel, avec la documentation sur l'idempotence. Source en anglais.