@workflow/world-testing 4.1.0-beta.59 → 4.1.0-beta.60

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -4182,7 +4182,7 @@ var require_token_util = __commonJS({
4182
4182
  getTokenPayload: /* @__PURE__ */ __name(() => getTokenPayload, "getTokenPayload"),
4183
4183
  getVercelCliToken: /* @__PURE__ */ __name(() => getVercelCliToken, "getVercelCliToken"),
4184
4184
  getVercelDataDir: /* @__PURE__ */ __name(() => getVercelDataDir, "getVercelDataDir"),
4185
- getVercelOidcToken: /* @__PURE__ */ __name(() => getVercelOidcToken5, "getVercelOidcToken"),
4185
+ getVercelOidcToken: /* @__PURE__ */ __name(() => getVercelOidcToken6, "getVercelOidcToken"),
4186
4186
  isExpired: /* @__PURE__ */ __name(() => isExpired, "isExpired"),
4187
4187
  loadToken: /* @__PURE__ */ __name(() => loadToken, "loadToken"),
4188
4188
  saveToken: /* @__PURE__ */ __name(() => saveToken, "saveToken")
@@ -4217,7 +4217,7 @@ var require_token_util = __commonJS({
4217
4217
  return JSON.parse(token).token;
4218
4218
  }
4219
4219
  __name(getVercelCliToken, "getVercelCliToken");
4220
- async function getVercelOidcToken5(authToken, projectId, teamId) {
4220
+ async function getVercelOidcToken6(authToken, projectId, teamId) {
4221
4221
  try {
4222
4222
  const url2 = `https://api.vercel.com/v1/projects/${projectId}/token?source=vercel-oidc-refresh${teamId ? `&teamId=${teamId}` : ""}`;
4223
4223
  const res = await fetch(url2, {
@@ -4237,7 +4237,7 @@ var require_token_util = __commonJS({
4237
4237
  throw new import_token_error.VercelOidcTokenError(`Failed to refresh OIDC token`, e);
4238
4238
  }
4239
4239
  }
4240
- __name(getVercelOidcToken5, "getVercelOidcToken");
4240
+ __name(getVercelOidcToken6, "getVercelOidcToken");
4241
4241
  function assertVercelOidcTokenResponse(res) {
4242
4242
  if (!res || typeof res !== "object") {
4243
4243
  throw new TypeError("Expected an object");
@@ -4417,13 +4417,13 @@ var require_get_vercel_oidc_token = __commonJS({
4417
4417
  }), mod), "__toCommonJS");
4418
4418
  var get_vercel_oidc_token_exports = {};
4419
4419
  __export2(get_vercel_oidc_token_exports, {
4420
- getVercelOidcToken: /* @__PURE__ */ __name(() => getVercelOidcToken5, "getVercelOidcToken"),
4420
+ getVercelOidcToken: /* @__PURE__ */ __name(() => getVercelOidcToken6, "getVercelOidcToken"),
4421
4421
  getVercelOidcTokenSync: /* @__PURE__ */ __name(() => getVercelOidcTokenSync2, "getVercelOidcTokenSync")
4422
4422
  });
4423
4423
  module2.exports = __toCommonJS2(get_vercel_oidc_token_exports);
4424
4424
  var import_get_context = require_get_context2();
4425
4425
  var import_token_error = require_token_error();
4426
- async function getVercelOidcToken5() {
4426
+ async function getVercelOidcToken6() {
4427
4427
  let token = "";
4428
4428
  let err;
4429
4429
  try {
@@ -4451,7 +4451,7 @@ ${error45.message}`;
4451
4451
  }
4452
4452
  return token;
4453
4453
  }
4454
- __name(getVercelOidcToken5, "getVercelOidcToken");
4454
+ __name(getVercelOidcToken6, "getVercelOidcToken");
4455
4455
  function getVercelOidcTokenSync2() {
4456
4456
  const token = (0, import_get_context.getContext)().headers?.["x-vercel-oidc-token"] ?? process.env.VERCEL_OIDC_TOKEN;
4457
4457
  if (!token) {
@@ -25191,7 +25191,7 @@ async function fetch2(...args) {
25191
25191
  return globalThis.fetch(...args);
25192
25192
  }
25193
25193
  __name(fetch2, "fetch");
25194
- registerStepFunction("step//workflow@4.1.0-beta.58//fetch", fetch2);
25194
+ registerStepFunction("step//workflow@4.1.0-beta.59//fetch", fetch2);
25195
25195
  // workflows/addition.ts
25196
25196
  async function add(num, num2) {
25197
25197
  return num + num2;
@@ -39600,6 +39600,18 @@ var WaitSchema = external_exports.object({
39600
39600
  updatedAt: external_exports.coerce.date(),
39601
39601
  specVersion: external_exports.number().optional()
39602
39602
  });
39603
+ // ../core/dist/encryption.js
39604
+ var KEY_LENGTH = 32;
39605
+ async function importKey(raw) {
39606
+ if (raw.byteLength !== KEY_LENGTH) {
39607
+ throw new Error(`Encryption key must be exactly ${KEY_LENGTH} bytes, got ${raw.byteLength}`);
39608
+ }
39609
+ return globalThis.crypto.subtle.importKey("raw", raw, "AES-GCM", false, [
39610
+ "encrypt",
39611
+ "decrypt"
39612
+ ]);
39613
+ }
39614
+ __name(importKey, "importKey");
39603
39615
  // ../serde/dist/index.js
39604
39616
  var WORKFLOW_SERIALIZE = Symbol.for("workflow-serialize");
39605
39617
  var WORKFLOW_DESERIALIZE = Symbol.for("workflow-deserialize");
@@ -44042,10 +44054,94 @@ function createLocalWorld(args) {
44042
44054
  };
44043
44055
  }
44044
44056
  __name(createLocalWorld, "createLocalWorld");
44057
+ // ../world-vercel/dist/encryption.js
44058
+ var import_node_crypto2 = require("node:crypto");
44059
+ var import_oidc2 = __toESM(require_dist(), 1);
44060
+ var KEY_BYTES = 32;
44061
+ async function deriveRunKey(deploymentKey, projectId, runId) {
44062
+ if (deploymentKey.length !== KEY_BYTES) {
44063
+ throw new Error(`Invalid deployment key length: expected ${KEY_BYTES} bytes for AES-256, got ${deploymentKey.length} bytes`);
44064
+ }
44065
+ if (!projectId || typeof projectId !== "string") {
44066
+ throw new Error("projectId must be a non-empty string");
44067
+ }
44068
+ const baseKey = await import_node_crypto2.webcrypto.subtle.importKey("raw", deploymentKey, "HKDF", false, [
44069
+ "deriveBits"
44070
+ ]);
44071
+ const info = new TextEncoder().encode(`${projectId}|${runId}`);
44072
+ const derivedBits = await import_node_crypto2.webcrypto.subtle.deriveBits({
44073
+ name: "HKDF",
44074
+ hash: "SHA-256",
44075
+ salt: new Uint8Array(32),
44076
+ info
44077
+ }, baseKey, KEY_BYTES * 8
44078
+ // bits
44079
+ );
44080
+ return new Uint8Array(derivedBits);
44081
+ }
44082
+ __name(deriveRunKey, "deriveRunKey");
44083
+ async function fetchRunKey(deploymentId, projectId, runId, options) {
44084
+ const oidcToken = await (0, import_oidc2.getVercelOidcToken)().catch(() => null);
44085
+ const token = options?.token ?? oidcToken ?? process.env.VERCEL_TOKEN;
44086
+ if (!token) {
44087
+ throw new Error("Cannot fetch run key: no OIDC token or VERCEL_TOKEN available");
44088
+ }
44089
+ const params = new URLSearchParams({
44090
+ projectId,
44091
+ runId
44092
+ });
44093
+ const response = await fetch(`https://api.vercel.com/v1/workflow/run-key/${deploymentId}?${params}`, {
44094
+ headers: {
44095
+ Authorization: `Bearer ${token}`
44096
+ }
44097
+ });
44098
+ if (!response.ok) {
44099
+ throw new Error(`Failed to fetch run key for ${runId} (deployment ${deploymentId}): HTTP ${response.status}`);
44100
+ }
44101
+ const data = await response.json();
44102
+ const result = object({
44103
+ key: string2()
44104
+ }).safeParse(data);
44105
+ if (!result.success) {
44106
+ throw new Error('Invalid response from Vercel API, missing "key" field');
44107
+ }
44108
+ return Buffer.from(result.data.key, "base64");
44109
+ }
44110
+ __name(fetchRunKey, "fetchRunKey");
44111
+ function createGetEncryptionKeyForRun(projectId, token) {
44112
+ if (!projectId)
44113
+ return void 0;
44114
+ const currentDeploymentId = process.env.VERCEL_DEPLOYMENT_ID;
44115
+ let localDeploymentKey;
44116
+ function getLocalDeploymentKey() {
44117
+ if (localDeploymentKey)
44118
+ return localDeploymentKey;
44119
+ const deploymentKeyBase64 = process.env.VERCEL_DEPLOYMENT_KEY;
44120
+ if (!deploymentKeyBase64)
44121
+ return void 0;
44122
+ localDeploymentKey = Buffer.from(deploymentKeyBase64, "base64");
44123
+ return localDeploymentKey;
44124
+ }
44125
+ __name(getLocalDeploymentKey, "getLocalDeploymentKey");
44126
+ return /* @__PURE__ */ __name(async function getEncryptionKeyForRun(run, context) {
44127
+ const runId = typeof run === "string" ? run : run.runId;
44128
+ const deploymentId = typeof run === "string" ? context?.deploymentId : run.deploymentId;
44129
+ if (!deploymentId || deploymentId === currentDeploymentId) {
44130
+ const localKey = getLocalDeploymentKey();
44131
+ if (!localKey)
44132
+ return void 0;
44133
+ return deriveRunKey(localKey, projectId, runId);
44134
+ }
44135
+ return fetchRunKey(deploymentId, projectId, runId, {
44136
+ token
44137
+ });
44138
+ }, "getEncryptionKeyForRun");
44139
+ }
44140
+ __name(createGetEncryptionKeyForRun, "createGetEncryptionKeyForRun");
44045
44141
  // ../../node_modules/.pnpm/@vercel+queue@0.0.0-alpha.38/node_modules/@vercel/queue/dist/web.mjs
44046
44142
  var fs2 = __toESM(require("fs"), 1);
44047
44143
  var path9 = __toESM(require("path"), 1);
44048
- var import_oidc2 = __toESM(require_dist(), 1);
44144
+ var import_oidc3 = __toESM(require_dist(), 1);
44049
44145
  var MessageNotFoundError2 = class extends Error {
44050
44146
  static {
44051
44147
  __name(this, "MessageNotFoundError");
@@ -44480,7 +44576,7 @@ var QueueClient2 = class {
44480
44576
  if (this.providedToken) {
44481
44577
  return this.providedToken;
44482
44578
  }
44483
- const token = await (0, import_oidc2.getVercelOidcToken)();
44579
+ const token = await (0, import_oidc3.getVercelOidcToken)();
44484
44580
  if (!token) {
44485
44581
  throw new Error("Failed to get OIDC token from Vercel Functions. Make sure you are running in a Vercel Function environment, or provide a token explicitly.\n\nTo set up your environment:\n1. Link your project: 'vercel link'\n2. Pull environment variables: 'vercel env pull'\n3. Run with environment: 'dotenv -e .env.local -- your-command'");
44486
44582
  }
@@ -45386,7 +45482,7 @@ __name(handleCallback2, "handleCallback2");
45386
45482
  // ../world-vercel/dist/utils.js
45387
45483
  var import_node_os = __toESM(require("node:os"), 1);
45388
45484
  var import_node_util2 = require("node:util");
45389
- var import_oidc3 = __toESM(require_dist(), 1);
45485
+ var import_oidc4 = __toESM(require_dist(), 1);
45390
45486
  // ../../node_modules/.pnpm/cbor-x@1.6.0/node_modules/cbor-x/decode.js
45391
45487
  var decoder;
45392
45488
  try {
@@ -48005,7 +48101,7 @@ var RpcSystem3 = SemanticConvention3("rpc.system");
48005
48101
  var RpcService3 = SemanticConvention3("rpc.service");
48006
48102
  var RpcMethod3 = SemanticConvention3("rpc.method");
48007
48103
  // ../world-vercel/dist/version.js
48008
- var version2 = "4.1.0-beta.33";
48104
+ var version2 = "4.1.0-beta.34";
48009
48105
  // ../world-vercel/dist/utils.js
48010
48106
  var WORKFLOW_SERVER_URL_OVERRIDE = "";
48011
48107
  var DEFAULT_RESOLVE_DATA_OPTION2 = "all";
@@ -48093,7 +48189,7 @@ async function getHttpConfig(config3) {
48093
48189
  const headers = getHeaders(config3, {
48094
48190
  usingProxy
48095
48191
  });
48096
- const token = config3?.token ?? await (0, import_oidc3.getVercelOidcToken)();
48192
+ const token = config3?.token ?? await (0, import_oidc4.getVercelOidcToken)();
48097
48193
  if (token) {
48098
48194
  headers.set("Authorization", `Bearer ${token}`);
48099
48195
  }
@@ -48991,10 +49087,12 @@ function createStreamer2(config3) {
48991
49087
  __name(createStreamer2, "createStreamer");
48992
49088
  // ../world-vercel/dist/index.js
48993
49089
  function createVercelWorld(config3) {
49090
+ const projectId = config3?.projectConfig?.projectId || process.env.VERCEL_PROJECT_ID;
48994
49091
  return {
48995
49092
  ...createQueue2(config3),
48996
49093
  ...createStorage2(config3),
48997
- ...createStreamer2(config3)
49094
+ ...createStreamer2(config3),
49095
+ getEncryptionKeyForRun: createGetEncryptionKeyForRun(projectId, config3?.token)
48998
49096
  };
48999
49097
  }
49000
49098
  __name(createVercelWorld, "createVercelWorld");
@@ -49883,12 +49981,15 @@ __name(withServerErrorRetry, "withServerErrorRetry");
49883
49981
  async function getHookByTokenWithKey(token) {
49884
49982
  const world = getWorld();
49885
49983
  const hook = await world.hooks.getByToken(token);
49886
- const encryptionKey = await world.getEncryptionKeyForRun?.(hook.runId);
49984
+ const run = await world.runs.get(hook.runId);
49985
+ const rawKey = await world.getEncryptionKeyForRun?.(run);
49986
+ const encryptionKey = rawKey ? await importKey(rawKey) : void 0;
49887
49987
  if (typeof hook.metadata !== "undefined") {
49888
49988
  hook.metadata = await hydrateStepArguments(hook.metadata, hook.runId, encryptionKey);
49889
49989
  }
49890
49990
  return {
49891
49991
  hook,
49992
+ run,
49892
49993
  encryptionKey
49893
49994
  };
49894
49995
  }
@@ -49899,15 +50000,24 @@ async function resumeHook(tokenOrHook, payload, encryptionKeyOverride) {
49899
50000
  const world = getWorld();
49900
50001
  try {
49901
50002
  let hook;
50003
+ let workflowRun;
49902
50004
  let encryptionKey;
49903
50005
  if (typeof tokenOrHook === "string") {
49904
50006
  const result = await getHookByTokenWithKey(tokenOrHook);
49905
50007
  hook = result.hook;
50008
+ workflowRun = result.run;
49906
50009
  encryptionKey = encryptionKeyOverride ?? result.encryptionKey;
49907
50010
  }
49908
50011
  else {
49909
50012
  hook = tokenOrHook;
49910
- encryptionKey = encryptionKeyOverride ?? await world.getEncryptionKeyForRun?.(hook.runId);
50013
+ workflowRun = await world.runs.get(hook.runId);
50014
+ if (encryptionKeyOverride) {
50015
+ encryptionKey = encryptionKeyOverride;
50016
+ }
50017
+ else {
50018
+ const rawKey = await world.getEncryptionKeyForRun?.(workflowRun);
50019
+ encryptionKey = rawKey ? await importKey(rawKey) : void 0;
50020
+ }
49911
50021
  }
49912
50022
  span?.setAttributes({
49913
50023
  ...HookToken(hook.token),
@@ -49931,7 +50041,6 @@ async function resumeHook(tokenOrHook, payload, encryptionKeyOverride) {
49931
50041
  }, {
49932
50042
  v1Compat
49933
50043
  });
49934
- const workflowRun = await world.runs.get(hook.runId);
49935
50044
  span?.setAttributes({
49936
50045
  ...WorkflowName(workflowRun.workflowName)
49937
50046
  });
@@ -50241,7 +50350,7 @@ var stepHandler = getWorldHandlers().createQueueHandler("__wkf_step_", async (me
50241
50350
  };
50242
50351
  }
50243
50352
  if (err.status === 410) {
50244
- console.warn(`Workflow run "${workflowRunId}" has already completed, skipping step "${stepId}": ${err.message}`);
50353
+ runtimeLogger.info(`Workflow run "${workflowRunId}" has already completed, skipping step "${stepId}": ${err.message}`);
50245
50354
  return;
50246
50355
  }
50247
50356
  if (err.status === 409) {
@@ -50311,15 +50420,29 @@ var stepHandler = getWorldHandlers().createQueueHandler("__wkf_step_", async (me
50311
50420
  stepName,
50312
50421
  retryCount
50313
50422
  });
50314
- await world.events.create(workflowRunId, {
50315
- eventType: "step_failed",
50316
- specVersion: SPEC_VERSION_CURRENT,
50317
- correlationId: stepId,
50318
- eventData: {
50319
- error: errorMessage,
50320
- stack: step.error?.stack
50423
+ try {
50424
+ await world.events.create(workflowRunId, {
50425
+ eventType: "step_failed",
50426
+ specVersion: SPEC_VERSION_CURRENT,
50427
+ correlationId: stepId,
50428
+ eventData: {
50429
+ error: errorMessage,
50430
+ stack: step.error?.stack
50431
+ }
50432
+ });
50433
+ }
50434
+ catch (err) {
50435
+ if (WorkflowAPIError.is(err) && err.status === 409) {
50436
+ runtimeLogger.warn("Tried failing step, but step has already finished.", {
50437
+ workflowRunId,
50438
+ stepId,
50439
+ stepName,
50440
+ message: err.message
50441
+ });
50442
+ return;
50321
50443
  }
50322
- });
50444
+ throw err;
50445
+ }
50323
50446
  span?.setAttributes({
50324
50447
  ...StepStatus("failed"),
50325
50448
  ...StepRetryExhausted(true)
@@ -50338,7 +50461,8 @@ var stepHandler = getWorldHandlers().createQueueHandler("__wkf_step_", async (me
50338
50461
  }
50339
50462
  const stepStartedAt = step.startedAt;
50340
50463
  const ops = [];
50341
- const encryptionKey = await world.getEncryptionKeyForRun?.(workflowRunId);
50464
+ const rawKey = await world.getEncryptionKeyForRun?.(workflowRunId);
50465
+ const encryptionKey = rawKey ? await importKey(rawKey) : void 0;
50342
50466
  const hydratedInput = await trace("step.hydrate", {}, async (hydrateSpan) => {
50343
50467
  const startTime = Date.now();
50344
50468
  const result2 = await hydrateStepArguments(step.input, workflowRunId, encryptionKey, ops);
@@ -50389,6 +50513,7 @@ var stepHandler = getWorldHandlers().createQueueHandler("__wkf_step_", async (me
50389
50513
  if (!isAbortError)
50390
50514
  throw err;
50391
50515
  }));
50516
+ let stepCompleted409 = false;
50392
50517
  const [, traceCarrier] = await Promise.all([
50393
50518
  withServerErrorRetry(() => world.events.create(workflowRunId, {
50394
50519
  eventType: "step_completed",
@@ -50397,9 +50522,24 @@ var stepHandler = getWorldHandlers().createQueueHandler("__wkf_step_", async (me
50397
50522
  eventData: {
50398
50523
  result
50399
50524
  }
50400
- })),
50525
+ })).catch((err) => {
50526
+ if (WorkflowAPIError.is(err) && err.status === 409) {
50527
+ runtimeLogger.warn("Tried completing step, but step has already finished.", {
50528
+ workflowRunId,
50529
+ stepId,
50530
+ stepName,
50531
+ message: err.message
50532
+ });
50533
+ stepCompleted409 = true;
50534
+ return;
50535
+ }
50536
+ throw err;
50537
+ }),
50401
50538
  serializeTraceCarrier()
50402
50539
  ]);
50540
+ if (stepCompleted409) {
50541
+ return;
50542
+ }
50403
50543
  span?.setAttributes({
50404
50544
  ...StepStatus("completed"),
50405
50545
  ...StepResultType(typeof result)
@@ -50453,15 +50593,29 @@ var stepHandler = getWorldHandlers().createQueueHandler("__wkf_step_", async (me
50453
50593
  stepName,
50454
50594
  errorStack: normalizedStack
50455
50595
  });
50456
- await withServerErrorRetry(() => world.events.create(workflowRunId, {
50457
- eventType: "step_failed",
50458
- specVersion: SPEC_VERSION_CURRENT,
50459
- correlationId: stepId,
50460
- eventData: {
50461
- error: normalizedError.message,
50462
- stack: normalizedStack
50596
+ try {
50597
+ await withServerErrorRetry(() => world.events.create(workflowRunId, {
50598
+ eventType: "step_failed",
50599
+ specVersion: SPEC_VERSION_CURRENT,
50600
+ correlationId: stepId,
50601
+ eventData: {
50602
+ error: normalizedError.message,
50603
+ stack: normalizedStack
50604
+ }
50605
+ }));
50606
+ }
50607
+ catch (stepFailErr) {
50608
+ if (WorkflowAPIError.is(stepFailErr) && stepFailErr.status === 409) {
50609
+ runtimeLogger.warn("Tried failing step, but step has already finished.", {
50610
+ workflowRunId,
50611
+ stepId,
50612
+ stepName,
50613
+ message: stepFailErr.message
50614
+ });
50615
+ return;
50463
50616
  }
50464
- }));
50617
+ throw stepFailErr;
50618
+ }
50465
50619
  span?.setAttributes({
50466
50620
  ...StepStatus("failed"),
50467
50621
  ...StepFatalError(true)
@@ -50484,15 +50638,29 @@ var stepHandler = getWorldHandlers().createQueueHandler("__wkf_step_", async (me
50484
50638
  errorStack: normalizedStack
50485
50639
  });
50486
50640
  const errorMessage = `Step "${stepName}" failed after ${maxRetries2} ${pluralize("retry", "retries", maxRetries2)}: ${normalizedError.message}`;
50487
- await withServerErrorRetry(() => world.events.create(workflowRunId, {
50488
- eventType: "step_failed",
50489
- specVersion: SPEC_VERSION_CURRENT,
50490
- correlationId: stepId,
50491
- eventData: {
50492
- error: errorMessage,
50493
- stack: normalizedStack
50641
+ try {
50642
+ await withServerErrorRetry(() => world.events.create(workflowRunId, {
50643
+ eventType: "step_failed",
50644
+ specVersion: SPEC_VERSION_CURRENT,
50645
+ correlationId: stepId,
50646
+ eventData: {
50647
+ error: errorMessage,
50648
+ stack: normalizedStack
50649
+ }
50650
+ }));
50651
+ }
50652
+ catch (stepFailErr) {
50653
+ if (WorkflowAPIError.is(stepFailErr) && stepFailErr.status === 409) {
50654
+ runtimeLogger.warn("Tried failing step, but step has already finished.", {
50655
+ workflowRunId,
50656
+ stepId,
50657
+ stepName,
50658
+ message: stepFailErr.message
50659
+ });
50660
+ return;
50494
50661
  }
50495
- }));
50662
+ throw stepFailErr;
50663
+ }
50496
50664
  span?.setAttributes({
50497
50665
  ...StepStatus("failed"),
50498
50666
  ...StepRetryExhausted(true)
@@ -50515,18 +50683,32 @@ var stepHandler = getWorldHandlers().createQueueHandler("__wkf_step_", async (me
50515
50683
  errorStack: normalizedStack
50516
50684
  });
50517
50685
  }
50518
- await withServerErrorRetry(() => world.events.create(workflowRunId, {
50519
- eventType: "step_retrying",
50520
- specVersion: SPEC_VERSION_CURRENT,
50521
- correlationId: stepId,
50522
- eventData: {
50523
- error: normalizedError.message,
50524
- stack: normalizedStack,
50525
- ...RetryableError.is(err) && {
50526
- retryAfter: err.retryAfter
50686
+ try {
50687
+ await withServerErrorRetry(() => world.events.create(workflowRunId, {
50688
+ eventType: "step_retrying",
50689
+ specVersion: SPEC_VERSION_CURRENT,
50690
+ correlationId: stepId,
50691
+ eventData: {
50692
+ error: normalizedError.message,
50693
+ stack: normalizedStack,
50694
+ ...RetryableError.is(err) && {
50695
+ retryAfter: err.retryAfter
50696
+ }
50527
50697
  }
50698
+ }));
50699
+ }
50700
+ catch (stepRetryErr) {
50701
+ if (WorkflowAPIError.is(stepRetryErr) && stepRetryErr.status === 409) {
50702
+ runtimeLogger.warn("Tried retrying step, but step has already finished.", {
50703
+ workflowRunId,
50704
+ stepId,
50705
+ stepName,
50706
+ message: stepRetryErr.message
50707
+ });
50708
+ return;
50528
50709
  }
50529
- }));
50710
+ throw stepRetryErr;
50711
+ }
50530
50712
  const timeoutSeconds = Math.max(1, RetryableError.is(err) ? Math.ceil((+err.retryAfter.getTime() - Date.now()) / 1e3) : 1);
50531
50713
  span?.setAttributes({
50532
50714
  ...StepRetryTimeoutSeconds(timeoutSeconds),