Skip to content

Commit f09be64

Browse files
Sg312waleedlatif1
authored andcommitted
fix(import): fix missing blocks in import if undefined keys exist (#2674)
1 parent c22d10d commit f09be64

File tree

2 files changed

+80
-1
lines changed

2 files changed

+80
-1
lines changed

apps/sim/lib/workflows/credentials/credential-extractor.ts

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,49 @@ function formatFieldName(fieldName: string): string {
161161
.join(' ')
162162
}
163163

164+
/**
165+
* Remove malformed subBlocks from a block that may have been created by bugs.
166+
* This includes subBlocks with:
167+
* - Key "undefined" (caused by assigning to undefined key)
168+
* - Missing required `id` field
169+
* - Type "unknown" (indicates malformed data)
170+
*/
171+
function removeMalformedSubBlocks(block: any): void {
172+
if (!block.subBlocks) return
173+
174+
const keysToRemove: string[] = []
175+
176+
Object.entries(block.subBlocks).forEach(([key, subBlock]: [string, any]) => {
177+
// Flag subBlocks with invalid keys (literal "undefined" string)
178+
if (key === 'undefined') {
179+
keysToRemove.push(key)
180+
return
181+
}
182+
183+
// Flag subBlocks that are null or not objects
184+
if (!subBlock || typeof subBlock !== 'object') {
185+
keysToRemove.push(key)
186+
return
187+
}
188+
189+
// Flag subBlocks with type "unknown" (malformed data)
190+
if (subBlock.type === 'unknown') {
191+
keysToRemove.push(key)
192+
return
193+
}
194+
195+
// Flag subBlocks missing required id field
196+
if (!subBlock.id) {
197+
keysToRemove.push(key)
198+
}
199+
})
200+
201+
// Remove the flagged keys
202+
keysToRemove.forEach((key) => {
203+
delete block.subBlocks[key]
204+
})
205+
}
206+
164207
/**
165208
* Sanitize workflow state by removing all credentials and workspace-specific data
166209
* This is used for both template creation and workflow export to ensure consistency
@@ -183,6 +226,9 @@ export function sanitizeWorkflowForSharing(
183226
Object.values(sanitized.blocks).forEach((block: any) => {
184227
if (!block?.type) return
185228

229+
// First, remove any malformed subBlocks that may have been created by bugs
230+
removeMalformedSubBlocks(block)
231+
186232
const blockConfig = getBlock(block.type)
187233

188234
// Process subBlocks with config

apps/sim/stores/workflows/json/importer.ts

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,14 @@ import type { WorkflowState } from '../workflow/types'
55
const logger = createLogger('WorkflowJsonImporter')
66

77
/**
8-
* Normalize subblock values by converting empty strings to null.
8+
* Normalize subblock values by converting empty strings to null and filtering out invalid subblocks.
99
* This provides backwards compatibility for workflows exported before the null sanitization fix,
1010
* preventing Zod validation errors like "Expected array, received string".
11+
*
12+
* Also filters out malformed subBlocks that may have been created by bugs in previous exports:
13+
* - SubBlocks with key "undefined" (caused by assigning to undefined key)
14+
* - SubBlocks missing required fields like `id`
15+
* - SubBlocks with `type: "unknown"` (indicates malformed data)
1116
*/
1217
function normalizeSubblockValues(blocks: Record<string, any>): Record<string, any> {
1318
const normalizedBlocks: Record<string, any> = {}
@@ -19,6 +24,34 @@ function normalizeSubblockValues(blocks: Record<string, any>): Record<string, an
1924
const normalizedSubBlocks: Record<string, any> = {}
2025

2126
Object.entries(block.subBlocks).forEach(([subBlockId, subBlock]: [string, any]) => {
27+
// Skip subBlocks with invalid keys (literal "undefined" string)
28+
if (subBlockId === 'undefined') {
29+
logger.warn(`Skipping malformed subBlock with key "undefined" in block ${blockId}`)
30+
return
31+
}
32+
33+
// Skip subBlocks that are null or not objects
34+
if (!subBlock || typeof subBlock !== 'object') {
35+
logger.warn(`Skipping invalid subBlock ${subBlockId} in block ${blockId}: not an object`)
36+
return
37+
}
38+
39+
// Skip subBlocks with type "unknown" (malformed data)
40+
if (subBlock.type === 'unknown') {
41+
logger.warn(
42+
`Skipping malformed subBlock ${subBlockId} in block ${blockId}: type is "unknown"`
43+
)
44+
return
45+
}
46+
47+
// Skip subBlocks missing required id field
48+
if (!subBlock.id) {
49+
logger.warn(
50+
`Skipping malformed subBlock ${subBlockId} in block ${blockId}: missing id field`
51+
)
52+
return
53+
}
54+
2255
const normalizedSubBlock = { ...subBlock }
2356

2457
// Convert empty strings to null for consistency

0 commit comments

Comments
 (0)