diff --git a/.changeset/replay-specversion-probe.md b/.changeset/replay-specversion-probe.md new file mode 100644 index 0000000000..e411a8c486 --- /dev/null +++ b/.changeset/replay-specversion-probe.md @@ -0,0 +1,5 @@ +--- +'@workflow/web': patch +--- + +Replay/Re-run probes the target deployment's specVersion via health check before recreating the run, so the correct queue transport (JSON for old deployments, CBOR for new) is used. Falls back to the original run's specVersion if the probe fails. diff --git a/packages/web/app/server/workflow-server-actions.server.ts b/packages/web/app/server/workflow-server-actions.server.ts index ca072d1b77..4d773a04d7 100644 --- a/packages/web/app/server/workflow-server-actions.server.ts +++ b/packages/web/app/server/workflow-server-actions.server.ts @@ -815,11 +815,35 @@ export async function recreateRun( ): Promise> { try { const world = await getWorldFromEnv({ ...worldEnv }); + + // Probe the target deployment's specVersion via health check so we use + // the correct queue transport (JSON for old deployments, CBOR for new). + // Falls back to the run's specVersion inside recreateRunFromExisting + // if the probe fails (e.g. old deployment without health check support). + let specVersion: number | undefined; + try { + let targetDeploymentId = deploymentId; + if (!targetDeploymentId) { + const run = await world.runs.get(runId, { resolveData: 'none' }); + targetDeploymentId = run.deploymentId; + } + const hc = await healthCheck(world, 'workflow', { + deploymentId: targetDeploymentId, + timeout: 10_000, + }); + if (hc.healthy && hc.specVersion != null) { + specVersion = hc.specVersion; + } + } catch { + // Health check failed — fall back to run's specVersion. + } + const newRunId = await workflowRunHelpers.recreateRunFromExisting( world, runId, { deploymentId, + specVersion, } ); return createResponse(newRunId);