diff --git a/apps/sim/app/workspace/[workspaceId]/logs/utils.ts b/apps/sim/app/workspace/[workspaceId]/logs/utils.ts
index 1a35685c8..570262d10 100644
--- a/apps/sim/app/workspace/[workspaceId]/logs/utils.ts
+++ b/apps/sim/app/workspace/[workspaceId]/logs/utils.ts
@@ -370,7 +370,7 @@ export function mapToExecutionLogAlt(log: RawLogResponse): ExecutionLog {
*/
export function formatLatency(ms: number): string {
if (!Number.isFinite(ms) || ms <= 0) return '—'
- return formatDuration(ms, { precision: 2 })
+ return formatDuration(ms, { precision: 2 }) ?? '—'
}
export const formatDate = (dateString: string) => {
diff --git a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/terminal/terminal.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/terminal/terminal.tsx
index c357d8c80..540f97bba 100644
--- a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/terminal/terminal.tsx
+++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/terminal/terminal.tsx
@@ -128,7 +128,7 @@ const BlockRow = memo(function BlockRow({
@@ -201,7 +201,7 @@ const IterationNodeRow = memo(function IterationNodeRow({
@@ -314,7 +314,7 @@ const SubflowNodeRow = memo(function SubflowNodeRow({
diff --git a/apps/sim/background/workspace-notification-delivery.ts b/apps/sim/background/workspace-notification-delivery.ts
index 68bfa2fe8..0d9a8254b 100644
--- a/apps/sim/background/workspace-notification-delivery.ts
+++ b/apps/sim/background/workspace-notification-delivery.ts
@@ -297,7 +297,7 @@ async function deliverEmail(
workflowName: payload.data.workflowName || 'Unknown Workflow',
status: payload.data.status,
trigger: payload.data.trigger,
- duration: formatDuration(payload.data.totalDurationMs, { precision: 1 }),
+ duration: formatDuration(payload.data.totalDurationMs, { precision: 1 }) ?? '-',
cost: formatCost(payload.data.cost),
logUrl,
alertReason,
@@ -310,7 +310,7 @@ async function deliverEmail(
to: subscription.emailRecipients,
subject,
html,
- text: `${subject}\n${alertReason ? `\nReason: ${alertReason}\n` : ''}\nWorkflow: ${payload.data.workflowName}\nStatus: ${statusText}\nTrigger: ${payload.data.trigger}\nDuration: ${formatDuration(payload.data.totalDurationMs, { precision: 1 })}\nCost: ${formatCost(payload.data.cost)}\n\nView Log: ${logUrl}${includedDataText}`,
+ text: `${subject}\n${alertReason ? `\nReason: ${alertReason}\n` : ''}\nWorkflow: ${payload.data.workflowName}\nStatus: ${statusText}\nTrigger: ${payload.data.trigger}\nDuration: ${formatDuration(payload.data.totalDurationMs, { precision: 1 }) ?? '-'}\nCost: ${formatCost(payload.data.cost)}\n\nView Log: ${logUrl}${includedDataText}`,
emailType: 'notifications',
})
@@ -370,7 +370,7 @@ async function deliverSlack(
{ type: 'mrkdwn', text: `*Trigger:*\n${payload.data.trigger}` },
{
type: 'mrkdwn',
- text: `*Duration:*\n${formatDuration(payload.data.totalDurationMs, { precision: 1 })}`,
+ text: `*Duration:*\n${formatDuration(payload.data.totalDurationMs, { precision: 1 }) ?? '-'}`,
},
{ type: 'mrkdwn', text: `*Cost:*\n${formatCost(payload.data.cost)}` },
],
diff --git a/apps/sim/lib/core/utils/formatting.ts b/apps/sim/lib/core/utils/formatting.ts
index 0e6dcd016..a7051df03 100644
--- a/apps/sim/lib/core/utils/formatting.ts
+++ b/apps/sim/lib/core/utils/formatting.ts
@@ -156,15 +156,15 @@ export function formatCompactTimestamp(iso: string): string {
* Format a duration to a human-readable format
* @param duration - Duration in milliseconds (number) or as string (e.g., "500ms")
* @param options - Optional formatting options
- * @param options.precision - Number of decimal places for seconds (default: 0)
- * @returns A formatted duration string
+ * @param options.precision - Number of decimal places for seconds (default: 0), trailing zeros are stripped
+ * @returns A formatted duration string, or null if input is null/undefined
*/
export function formatDuration(
duration: number | string | undefined | null,
options?: { precision?: number }
-): string {
+): string | null {
if (duration === undefined || duration === null) {
- return '-'
+ return null
}
// Parse string durations (e.g., "500ms", "0.44ms", "1234")
@@ -192,7 +192,11 @@ export function formatDuration(
const seconds = ms / 1000
if (seconds < 60) {
- return precision > 0 ? `${seconds.toFixed(precision)}s` : `${Math.floor(seconds)}s`
+ if (precision > 0) {
+ // Strip trailing zeros (e.g., "5.00s" -> "5s", "5.10s" -> "5.1s")
+ return `${seconds.toFixed(precision).replace(/\.?0+$/, '')}s`
+ }
+ return `${Math.floor(seconds)}s`
}
const minutes = Math.floor(seconds / 60)