Skip to content

Commit dd6b077

Browse files
fix(tables): skip stale remap types when workflowId changes concurrently
1 parent 9cbcfcc commit dd6b077

1 file changed

Lines changed: 24 additions & 7 deletions

File tree

apps/sim/lib/table/service.ts

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3243,12 +3243,17 @@ export async function updateWorkflowGroup(
32433243
// unchanged (workflow deleted, block removed). The result is applied against
32443244
// the fresh schema under the lock in phase 2.
32453245
const remapLeafTypeByColumn = new Map<string, ColumnDefinition['type']>()
3246+
// The workflow id the leaf types above were resolved against. Phase 2 only
3247+
// applies the resolved types if the group still points at this workflow under
3248+
// the lock — a concurrent `workflowId` change would make them stale.
3249+
let resolvedForWorkflowId: string | undefined
32463250
if (mappingUpdates.length > 0) {
32473251
try {
32483252
const preTable = await getTableById(data.tableId)
32493253
const preGroup = preTable?.schema.workflowGroups?.find((g) => g.id === data.groupId)
32503254
const targetWorkflowId = data.workflowId ?? preGroup?.workflowId
32513255
if (targetWorkflowId) {
3256+
resolvedForWorkflowId = targetWorkflowId
32523257
const [
32533258
{ loadWorkflowFromNormalizedTables },
32543259
{ flattenWorkflowOutputs },
@@ -3326,13 +3331,25 @@ export async function updateWorkflowGroup(
33263331
return { ...o, blockId: u.blockId, path: u.path }
33273332
})
33283333

3329-
const colByName = new Map(schema.columns.map((c) => [c.name, c]))
3330-
for (const u of mappingUpdates) {
3331-
const newType = remapLeafTypeByColumn.get(u.columnName)
3332-
if (!newType) continue
3333-
const oldType = colByName.get(u.columnName)?.type
3334-
if (newType !== oldType) {
3335-
remappedColumnTypes.set(u.columnName, newType)
3334+
// Only apply the out-of-lock leaf-type resolution if the group still
3335+
// points at the workflow we resolved against. If a concurrent writer
3336+
// changed `workflowId` between phase 1 and now, those types are stale —
3337+
// leave column types unchanged (best-effort, same as a resolution
3338+
// failure) rather than stamping types from the old workflow.
3339+
const finalWorkflowId = data.workflowId ?? group.workflowId
3340+
if (remapLeafTypeByColumn.size > 0 && resolvedForWorkflowId !== finalWorkflowId) {
3341+
logger.warn(
3342+
`[${requestId}] Workflow group "${data.groupId}" workflowId changed between leaf-type resolution and apply; leaving remapped column types unchanged.`
3343+
)
3344+
} else {
3345+
const colByName = new Map(schema.columns.map((c) => [c.name, c]))
3346+
for (const u of mappingUpdates) {
3347+
const newType = remapLeafTypeByColumn.get(u.columnName)
3348+
if (!newType) continue
3349+
const oldType = colByName.get(u.columnName)?.type
3350+
if (newType !== oldType) {
3351+
remappedColumnTypes.set(u.columnName, newType)
3352+
}
33363353
}
33373354
}
33383355
}

0 commit comments

Comments
 (0)