diff --git a/apps/webapp/app/presenters/v3/SpanPresenter.server.ts b/apps/webapp/app/presenters/v3/SpanPresenter.server.ts
index b2fd1d1c16..0c16a5cc99 100644
--- a/apps/webapp/app/presenters/v3/SpanPresenter.server.ts
+++ b/apps/webapp/app/presenters/v3/SpanPresenter.server.ts
@@ -218,6 +218,7 @@ export class SpanPresenter extends BasePresenter {
friendlyId: true,
},
},
+ replayedFromTaskRunFriendlyId: true,
},
where: span.originalRun
? {
@@ -331,6 +332,7 @@ export class SpanPresenter extends BasePresenter {
runtime: run.lockedToVersion?.runtime,
runtimeVersion: run.lockedToVersion?.runtimeVersion,
isTest: run.isTest,
+ replayedFromTaskRunFriendlyId: run.replayedFromTaskRunFriendlyId,
environmentId: run.runtimeEnvironment.id,
idempotencyKey: run.idempotencyKey,
idempotencyKeyExpiresAt: run.idempotencyKeyExpiresAt,
diff --git a/apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam.spans.$spanParam/route.tsx b/apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam.spans.$spanParam/route.tsx
index 22dbacde41..2c85b0aa56 100644
--- a/apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam.spans.$spanParam/route.tsx
+++ b/apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam.spans.$spanParam/route.tsx
@@ -63,6 +63,7 @@ import {
v3DeploymentVersionPath,
v3RunDownloadLogsPath,
v3RunPath,
+ v3RunRedirectPath,
v3RunSpanPath,
v3RunsPath,
v3SchedulePath,
@@ -592,6 +593,20 @@ function RunBody({
{run.isTest ? : "–"}
+ {run.replayedFromTaskRunFriendlyId && (
+
+ Replayed from
+
+
+ {run.replayedFromTaskRunFriendlyId}
+
+
+
+ )}
{environment && (
Environment
diff --git a/apps/webapp/app/runEngine/services/triggerTask.server.ts b/apps/webapp/app/runEngine/services/triggerTask.server.ts
index b621d7dee6..f19b532fd1 100644
--- a/apps/webapp/app/runEngine/services/triggerTask.server.ts
+++ b/apps/webapp/app/runEngine/services/triggerTask.server.ts
@@ -264,6 +264,7 @@ export class RunEngineTriggerTaskService {
spanId: event.spanId,
parentSpanId:
options.parentAsLinkType === "replay" ? undefined : event.traceparent?.spanId,
+ replayedFromTaskRunFriendlyId: options.replayedFromTaskRunFriendlyId,
lockedToVersionId: lockedToBackgroundWorker?.id,
taskVersion: lockedToBackgroundWorker?.version,
sdkVersion: lockedToBackgroundWorker?.sdkVersion,
diff --git a/apps/webapp/app/v3/services/replayTaskRun.server.ts b/apps/webapp/app/v3/services/replayTaskRun.server.ts
index 5b7ca7098b..061e65029e 100644
--- a/apps/webapp/app/v3/services/replayTaskRun.server.ts
+++ b/apps/webapp/app/v3/services/replayTaskRun.server.ts
@@ -112,6 +112,7 @@ export class ReplayTaskRunService extends BaseService {
{
spanParentAsLink: true,
parentAsLinkType: "replay",
+ replayedFromTaskRunFriendlyId: existingTaskRun.friendlyId,
traceContext: {
traceparent: `00-${existingTaskRun.traceId}-${existingTaskRun.spanId}-01`,
},
diff --git a/apps/webapp/app/v3/services/triggerTask.server.ts b/apps/webapp/app/v3/services/triggerTask.server.ts
index 292c580fc8..baf348c6e9 100644
--- a/apps/webapp/app/v3/services/triggerTask.server.ts
+++ b/apps/webapp/app/v3/services/triggerTask.server.ts
@@ -33,6 +33,7 @@ export type TriggerTaskServiceOptions = {
scheduleInstanceId?: string;
queueTimestamp?: Date;
overrideCreatedAt?: Date;
+ replayedFromTaskRunFriendlyId?: string;
};
export class OutOfEntitlementError extends Error {
diff --git a/apps/webapp/app/v3/services/triggerTaskV1.server.ts b/apps/webapp/app/v3/services/triggerTaskV1.server.ts
index 5a913838ef..07f051feb1 100644
--- a/apps/webapp/app/v3/services/triggerTaskV1.server.ts
+++ b/apps/webapp/app/v3/services/triggerTaskV1.server.ts
@@ -427,6 +427,7 @@ export class TriggerTaskServiceV1 extends BaseService {
parentAttempt?.taskRun.id ??
dependentBatchRun?.dependentTaskAttempt?.taskRun.rootTaskRunId ??
dependentBatchRun?.dependentTaskAttempt?.taskRun.id,
+ replayedFromTaskRunFriendlyId: options.replayedFromTaskRunFriendlyId,
batchId: dependentBatchRun?.id ?? parentBatchRun?.id,
resumeParentOnCompletion: !!(dependentAttempt ?? dependentBatchRun),
depth,
diff --git a/internal-packages/database/prisma/migrations/20250711124003_add_replayed_from_run_friendly_id/migration.sql b/internal-packages/database/prisma/migrations/20250711124003_add_replayed_from_run_friendly_id/migration.sql
new file mode 100644
index 0000000000..2578e29f94
--- /dev/null
+++ b/internal-packages/database/prisma/migrations/20250711124003_add_replayed_from_run_friendly_id/migration.sql
@@ -0,0 +1 @@
+ALTER TABLE "TaskRun" ADD COLUMN "replayedFromTaskRunFriendlyId" TEXT;
\ No newline at end of file
diff --git a/internal-packages/database/prisma/schema.prisma b/internal-packages/database/prisma/schema.prisma
index 2ce5de2b5c..f9818a008c 100644
--- a/internal-packages/database/prisma/schema.prisma
+++ b/internal-packages/database/prisma/schema.prisma
@@ -644,6 +644,8 @@ model TaskRun {
logsDeletedAt DateTime?
+ replayedFromTaskRunFriendlyId String?
+
/// This represents the original task that that was triggered outside of a Trigger.dev task
rootTaskRun TaskRun? @relation("TaskRootRun", fields: [rootTaskRunId], references: [id], onDelete: SetNull, onUpdate: NoAction)
rootTaskRunId String?
diff --git a/internal-packages/run-engine/src/engine/index.ts b/internal-packages/run-engine/src/engine/index.ts
index 8ed9febb31..db3fd8b139 100644
--- a/internal-packages/run-engine/src/engine/index.ts
+++ b/internal-packages/run-engine/src/engine/index.ts
@@ -372,6 +372,7 @@ export class RunEngine {
tags,
parentTaskRunId,
rootTaskRunId,
+ replayedFromTaskRunFriendlyId,
batch,
resumeParentOnCompletion,
depth,
@@ -450,6 +451,7 @@ export class RunEngine {
oneTimeUseToken,
parentTaskRunId,
rootTaskRunId,
+ replayedFromTaskRunFriendlyId,
batchId: batch?.id,
resumeParentOnCompletion,
depth,
diff --git a/internal-packages/run-engine/src/engine/types.ts b/internal-packages/run-engine/src/engine/types.ts
index 87612b2bfa..5859ad6134 100644
--- a/internal-packages/run-engine/src/engine/types.ts
+++ b/internal-packages/run-engine/src/engine/types.ts
@@ -126,6 +126,7 @@ export type TriggerParams = {
tags: { id: string; name: string }[];
parentTaskRunId?: string;
rootTaskRunId?: string;
+ replayedFromTaskRunFriendlyId?: string;
batch?: {
id: string;
index: number;