Skip to content

Commit e57380d

Browse files
fix(table): paused workflow cells route through executeResumeJob; render Pending + viewable
Three connected issues with workflows that pause mid-cell (e.g. wait blocks): 1. `/api/resume/poll` (the time-pause auto-resumer) called `PauseResumeManager.startResumeExecution` directly, bypassing `executeResumeJob` from `background/resume-execution.ts`. The wrapper is where the cell-context restoration + cascade-loop continuation lives — without it, the resumed workflow ran to completion but never wrote the terminal state back to the table cell. Cell stays `pending` forever even though the underlying execution finished. Fix: dynamically import `executeResumeJob` and use it for the `'starting'` branch. Same primitive the trigger.dev `resumeExecutionTask` wraps — calling it directly handles both trigger.dev-disabled local dev and trigger.dev-enabled prod identically. 2. The cell renderer mapped `status: 'pending'` to `kind: 'queued'` (gray "Queued" badge) regardless of whether the run had started. A HITL-paused run has `status: 'pending'` + `jobId` prefixed `paused-` + a real `executionId` — semantically very different from "queued, hasn't run." Now renders as `pending-upstream` (the existing Pending pill) for paused-jobId rows. 3. Right-click "View execution" was disabled for `pending` cells (gated to `completed | error | running`), so users couldn't open the trace for a paused execution. Paused runs have a viewable trace (the executionId is real and the log row exists). Both the per-row context menu and the action-bar derivation now recognize `pending` + `paused-` jobId as a started run. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 757033a commit e57380d

3 files changed

Lines changed: 38 additions & 8 deletions

File tree

apps/sim/app/api/resume/poll/route.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -139,13 +139,21 @@ async function dispatchRow(row: DueRow, now: Date): Promise<RowResult> {
139139
})
140140

141141
if (enqueueResult.status === 'starting') {
142-
PauseResumeManager.startResumeExecution({
142+
// Route through `executeResumeJob` (not `PauseResumeManager.startResumeExecution`
143+
// directly) so cell-context restoration + cascade-loop continuation
144+
// fires. This is the same primitive the trigger.dev `resumeExecutionTask`
145+
// wraps — calling it directly handles both trigger.dev-disabled local
146+
// dev and trigger.dev-enabled prod identically.
147+
const { executeResumeJob } = await import('@/background/resume-execution')
148+
void executeResumeJob({
143149
resumeEntryId: enqueueResult.resumeEntryId,
144150
resumeExecutionId: enqueueResult.resumeExecutionId,
145-
pausedExecution: enqueueResult.pausedExecution,
151+
pausedExecutionId: enqueueResult.pausedExecution.id,
146152
contextId: enqueueResult.contextId,
147153
resumeInput: enqueueResult.resumeInput,
148154
userId: enqueueResult.userId,
155+
workflowId: row.workflowId,
156+
parentExecutionId: row.executionId,
149157
}).catch((error) => {
150158
logger.error('Background time-pause resume failed', {
151159
executionId: row.executionId,

apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/table-grid/cells/cell-render.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,12 @@ export function resolveCellRender({
6060
if (!isNull) return { kind: 'value', text: stringifyValue(value) }
6161

6262
if (inFlight && !(groupHasBlockErrors && !blockRunning)) {
63+
// A `pending` cell whose jobId starts with `paused-` is mid-pause
64+
// (workflow yielded for human-in-the-loop). Render as Pending rather
65+
// than Queued so the user can tell it's not just waiting to start.
66+
const isPaused =
67+
exec?.status === 'pending' && typeof exec.jobId === 'string' && exec.jobId.startsWith('paused-')
68+
if (isPaused) return { kind: 'pending-upstream' }
6369
if (exec?.status === 'queued' || exec?.status === 'pending') return { kind: 'queued' }
6470
return { kind: 'pending-upstream' }
6571
}

apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/table-grid/table-grid.tsx

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -659,12 +659,20 @@ export function TableGrid({
659659
if (_col && _gid) {
660660
const _exec = contextMenu.row.executions?.[_gid]
661661
contextMenuIsWorkflowColumn = true
662-
// Only `completed` / `error` / `running` cells are guaranteed to have a
663-
// server-side execution log. `queued` / `pending` haven't started yet;
664-
// `cancelled` may have been cancelled before the worker ever picked the
665-
// job up, so its executionId can't be relied on either.
662+
// Cells with a server-side execution log: `completed` / `error` /
663+
// `running`, plus HITL-paused runs (status `pending` with a `paused-`
664+
// jobId — has a real executionId + viewable trace). `queued` / plain
665+
// `pending` haven't started yet; `cancelled` may have been cancelled
666+
// before the worker ever picked the job up.
667+
const _isPaused =
668+
_exec?.status === 'pending' &&
669+
typeof _exec?.jobId === 'string' &&
670+
_exec.jobId.startsWith('paused-')
666671
contextMenuHasStartedRun =
667-
_exec?.status === 'completed' || _exec?.status === 'error' || _exec?.status === 'running'
672+
_exec?.status === 'completed' ||
673+
_exec?.status === 'error' ||
674+
_exec?.status === 'running' ||
675+
_isPaused
668676
contextMenuExecutionId = _exec?.executionId ?? null
669677
}
670678
}
@@ -2781,11 +2789,19 @@ export function TableGrid({
27812789
}
27822790
const exec = row.executions?.[groupId]
27832791
const status = exec?.status
2792+
// A `pending` execution with a `paused-` jobId is a HITL-paused run —
2793+
// it has a real executionId and a viewable trace, same as
2794+
// running/completed/error.
2795+
const isPaused =
2796+
status === 'pending' &&
2797+
typeof exec?.jobId === 'string' &&
2798+
exec.jobId.startsWith('paused-')
27842799
return {
27852800
rowId: row.id,
27862801
groupId,
27872802
executionId: exec?.executionId ?? null,
2788-
canViewExecution: status === 'completed' || status === 'error' || status === 'running',
2803+
canViewExecution:
2804+
status === 'completed' || status === 'error' || status === 'running' || isPaused,
27892805
}
27902806
}, [normalizedSelection, rows, displayColumns])
27912807

0 commit comments

Comments
 (0)