Skip to content

Commit dc081e5

Browse files
committed
fix(core): only fall back to the derived hash on a definitive not-found
A transient failure (503, connection error) of the verbatim attempt leaves that key's state unknown. Issuing the derived-hash reset anyway is a write against a key the caller may not have targeted, and it reports success while the verbatim run stays deduplicated. Now only a 404, a definitive miss, unlocks the fallback; any other error surfaces unchanged, exactly as previous versions behaved.
1 parent fa7634f commit dc081e5

2 files changed

Lines changed: 6 additions & 17 deletions

File tree

packages/core/src/v3/idempotencyKeys.test.ts

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -193,28 +193,13 @@ describe("resetIdempotencyKey", () => {
193193
expect(resetKeys).toEqual([digestShapedKey]);
194194
});
195195

196-
it("falls back to the derived hash when the verbatim attempt fails with a 503", async () => {
196+
it("does not reset the derived run when the verbatim attempt fails transiently", async () => {
197197
const created = await createIdempotencyKey(digestShapedKey, { scope: "global" });
198198

199199
resetIdempotencyKeyCatalog();
200200
statusByKey.set(digestShapedKey, 503);
201201
existingKeys = new Set([created]);
202202

203-
await resetIdempotencyKey(
204-
"my-task",
205-
digestShapedKey,
206-
{ scope: "global" },
207-
{ retry: { maxAttempts: 1 } }
208-
);
209-
210-
expect(resetKeys).toEqual([digestShapedKey, created]);
211-
});
212-
213-
it("surfaces the verbatim attempt's error when it fails with a 503 and the fallback finds nothing", async () => {
214-
const derived = await digestSHA256(digestShapedKey);
215-
statusByKey.set(digestShapedKey, 503);
216-
existingKeys = new Set();
217-
218203
await expect(
219204
resetIdempotencyKey(
220205
"my-task",
@@ -224,7 +209,7 @@ describe("resetIdempotencyKey", () => {
224209
)
225210
).rejects.toMatchObject({ status: 503 });
226211

227-
expect(resetKeys).toEqual([digestShapedKey, derived]);
212+
expect(resetKeys).toEqual([digestShapedKey]);
228213
});
229214

230215
it("surfaces the fallback's error when it fails with something other than a 404", async () => {

packages/core/src/v3/idempotencyKeys.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,10 @@ export async function resetIdempotencyKey(
292292
try {
293293
return await client.resetIdempotencyKey(taskIdentifier, idempotencyKey, requestOptions);
294294
} catch (error) {
295+
if (!(error instanceof NotFoundError)) {
296+
throw error;
297+
}
298+
295299
try {
296300
return await client.resetIdempotencyKey(taskIdentifier, hash, requestOptions);
297301
} catch (fallbackError) {

0 commit comments

Comments
 (0)