{"record":{"id":"39cc0674ac02c0b6","repo":"remotion-dev/remotion","slug":"no-effects-were-specified-for-deletion","errorCode":null,"errorMessage":"No effects were specified for deletion","messagePattern":"No effects were specified for deletion","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/browser-studio/src/browser-studio-operations.ts","lineNumber":916,"sourceCode":"\t\t\t\t});\n\t\t\t\tcontroller.applyMutation({\n\t\t\t\t\ttimelineSelection: null,\n\t\t\t\t\tfileName: absolutePath,\n\t\t\t\t\tnodePathMutationFiles: null,\n\t\t\t\t\tmutate: () => ({\n\t\t\t\t\t\t...project,\n\t\t\t\t\t\tfiles: {...project.files, [absolutePath]: result.output},\n\t\t\t\t\t}),\n\t\t\t\t});\n\t\t\t\treturn {success: true};\n\t\t\t} catch (error) {\n\t\t\t\treturn getStructuredError(error);\n\t\t\t}\n\t\t},\n\t\tdeleteEffects: async (request) => {\n\t\t\ttry {\n\t\t\t\tif (request.length === 0) {\n\t\t\t\t\tthrow new Error('No effects were specified for deletion');\n\t\t\t\t}\n\n\t\t\t\tconst project = getProject();\n\t\t\t\tconst groups = new Map<\n\t\t\t\t\tstring,\n\t\t\t\t\tArray<\n\t\t\t\t\t\t| {\n\t\t\t\t\t\t\t\ttype: 'single-effect';\n\t\t\t\t\t\t\t\teffectIndex: number;\n\t\t\t\t\t\t\t\tsequenceNodePath: SequenceNodePath;\n\t\t\t\t\t\t  }\n\t\t\t\t\t\t| {type: 'all-effects'; sequenceNodePath: SequenceNodePath}\n\t\t\t\t\t>\n\t\t\t\t>();\n\t\t\t\tfor (const item of request) {\n\t\t\t\t\tconst absolutePath = findProjectFile({\n\t\t\t\t\t\tfilePath: item.fileName,\n\t\t\t\t\t\tproject,","sourceCodeStart":898,"sourceCodeEnd":934,"githubUrl":"https://github.com/remotion-dev/remotion/blob/b2f4e34732f3c6c222ea029413e22dc402218cd7/packages/browser-studio/src/browser-studio-operations.ts#L898-L934","documentation":"deleteEffects guards against no-op requests: an empty request array means there is nothing to delete, so it throws immediately. The throw happens inside the operation's try block and is returned to the caller as a structured error result (via getStructuredError), not as a rejected promise.","triggerScenarios":"Calling effectOperations.deleteEffects([]) — e.g. a bulk-delete UI action where every selected effect was deselected or filtered out before the call.","commonSituations":"Select-none-then-delete flows; clear-all-effects buttons that compute the selection list incorrectly; defensive callers passing an array they never checked.","solutions":["Check request.length > 0 before calling deleteEffects.","Fix the selection logic that produced an empty delete list.","Disable the delete action in the UI when no effects are selected."],"exampleFix":"// before\nawait operations.effect.deleteEffects(selected);\n\n// after\nif (selected.length > 0) {\n  await operations.effect.deleteEffects(selected);\n}","handlingStrategy":"validation","validationCode":"if (request.length > 0) {\n  const result = await operations.effect.deleteEffects(request);\n}","typeGuard":"const isNonEmptyDeleteEffectsRequest = (\n  request: unknown[],\n): request is Array<{fileName: string; sequenceNodePath: SequenceNodePath}> =>\n  Array.isArray(request) && request.length > 0;","tryCatchPattern":null,"preventionTips":["Bind delete buttons to selection length so they cannot fire with an empty list.","Treat empty delete batches as a successful no-op in calling code."],"tags":["effects","validation","no-op"],"backgroundTag":"empty-request-rejected","analyzedSha":"b2f4e34732f3c6c222ea029413e22dc402218cd7","analyzedAt":"2026-08-22T21:45:17.748Z","contentChangedAt":"2026-08-22T21:45:17.748Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}