{"record":{"id":"065d34c2773f147b","repo":"remotion-dev/remotion","slug":"no-jsx-nodes-were-specified-for-duplication","errorCode":null,"errorMessage":"No JSX nodes were specified for duplication","messagePattern":"No JSX nodes were specified for duplication","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/browser-studio/src/browser-studio-operations.ts","lineNumber":1338,"sourceCode":"\t\t\t\tthrow new Error('Could not delete JSX nodes');\n\t\t\t}\n\n\t\t\treturn {success: true, nodePathMutation};\n\t\t} catch (error) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\treason: error instanceof Error ? error.message : String(error),\n\t\t\t\tstack: error instanceof Error && error.stack ? error.stack : '',\n\t\t\t};\n\t\t}\n\t};\n\n\tconst duplicateJsxNode: BrowserStudioOperations['duplicateJsxNode'] = async ({\n\t\tnodes,\n\t}) => {\n\t\ttry {\n\t\t\tif (nodes.length === 0) {\n\t\t\t\tthrow new Error('No JSX nodes were specified for duplication');\n\t\t\t}\n\n\t\t\tconst project = getProject();\n\t\t\tconst nodesByFile = new Map<\n\t\t\t\tstring,\n\t\t\t\t(typeof nodes)[number]['nodePath'][]\n\t\t\t>();\n\t\t\tfor (const node of nodes) {\n\t\t\t\tconst fileName = findProjectFile({\n\t\t\t\t\tfilePath: node.fileName,\n\t\t\t\t\tproject,\n\t\t\t\t});\n\t\t\t\tconst fileNodes = nodesByFile.get(fileName) ?? [];\n\t\t\t\tfileNodes.push(node.nodePath);\n\t\t\t\tnodesByFile.set(fileName, fileNodes);\n\t\t\t}\n\n\t\t\tconst updates = await Promise.all(","sourceCodeStart":1320,"sourceCodeEnd":1356,"githubUrl":"https://github.com/remotion-dev/remotion/blob/b2f4e34732f3c6c222ea029413e22dc402218cd7/packages/browser-studio/src/browser-studio-operations.ts#L1320-L1356","documentation":"duplicateJsxNode requires a non-empty array of JSX nodes to duplicate. Passing an empty nodes array is a caller bug and throws immediately.","triggerScenarios":"Calling browserStudioOperations.duplicateJsxNode({nodes: []}), e.g. the UI invoking duplicate with an empty selection or a caller mapping over an empty selection list.","commonSituations":"A keyboard shortcut or context-menu handler firing with no nodes selected, or a selection state that was cleared before the duplicate action ran.","solutions":["Guard the call: only invoke duplicateJsxNode when the selection is non-empty","Fix the caller that builds the nodes array from selection state","Check for a race where selection was cleared before the operation ran"],"exampleFix":"// before\nawait ops.duplicateJsxNode({nodes});\n\n// after\nif (nodes.length > 0) {\n  await ops.duplicateJsxNode({nodes});\n}","handlingStrategy":"validation","validationCode":"if (nodes.length === 0) { return; /* nothing to duplicate */ }","typeGuard":"const hasNodes = (n: {nodePath: unknown}[]) => n.length > 0;","tryCatchPattern":null,"preventionTips":["Gate duplicate actions on a non-empty selection in UI handlers","Clear pending operations when selection changes"],"tags":["browser-studio","duplicate","jsx","validation"],"backgroundTag":"empty-array-argument","analyzedSha":"b2f4e34732f3c6c222ea029413e22dc402218cd7","analyzedAt":"2026-08-28T15:39:09.316Z","contentChangedAt":"2026-08-28T15:39:09.316Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}