{"record":{"id":"e8630ca12671e0f3","repo":"windmill-labs/windmill","slug":"cannot-reject-module-without-a-beforeflow-snapshot","errorCode":null,"errorMessage":"Cannot reject module without a beforeFlow snapshot","messagePattern":"Cannot reject module without a beforeFlow snapshot","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"frontend/src/lib/components/flows/flowDiffManager.svelte.ts","lineNumber":315,"sourceCode":"\t\t\t}\n\t\t} else if (info.action === 'modified') {\n\t\t\t// Modified: Apply modifications to beforeFlow module\n\t\t\tconst beforeModule = findModuleInFlow(beforeFlow.value, actualId) ?? undefined\n\t\t\tconst afterModule = findModuleInFlow(currentFlow, actualId) ?? undefined\n\n\t\t\tif (beforeModule && afterModule) {\n\t\t\t\treplaceFlowModule(beforeModule, $state.snapshot(afterModule))\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Reject a module action (revert the changes)\n\t * Removes the action from tracking after rejection\n\t */\n\tfunction rejectModule(id: string, flowStore?: StateStore<ExtendedOpenFlow>) {\n\t\tif (!beforeFlow) {\n\t\t\tthrow new Error('Cannot reject module without a beforeFlow snapshot')\n\t\t}\n\n\t\tconst actualId = id.startsWith(DUPLICATE_MODULE_PREFIX)\n\t\t\t? id.substring(DUPLICATE_MODULE_PREFIX.length)\n\t\t\t: id\n\t\tconst info = moduleActions[id]\n\n\t\tif (!info) return\n\n\t\t// Only perform revert operations if flowStore is provided\n\t\tif (flowStore) {\n\t\t\tif (id === SPECIAL_MODULE_IDS.INPUT) {\n\t\t\t\t// Revert input schema changes\n\t\t\t\tflowStore.val.schema = beforeFlow.schema\n\t\t\t\tcurrentInputSchema = flowStore.val.schema\n\t\t\t} else if (info.action === 'added') {\n\t\t\t\t// Added in after: Remove from flowStore (currentFlow)\n\t\t\t\t// deleteModuleFromFlow handles the case where the module was already deleted (e.g., with its parent)","sourceCodeStart":297,"sourceCodeEnd":333,"githubUrl":"https://github.com/windmill-labs/windmill/blob/e474e8803ce2ff5c2df09a58dab51d45f5c922ca/frontend/src/lib/components/flows/flowDiffManager.svelte.ts#L297-L333","documentation":"rejectModule reverts one module-level change detected by the flow diff manager by restoring it from the `beforeFlow` snapshot taken when the diff session started. If no snapshot was captured (`beforeFlow` is unset) there is nothing to revert to, so it throws 'Cannot reject module without a beforeFlow snapshot'. This is an internal-state precondition: rejecting a diff is meaningless without the baseline.","triggerScenarios":"Calling rejectModule(id, flowStore?) — directly or via rejectAll — on a flowDiffManager instance created without a beforeFlow snapshot (e.g. manager instantiated outside a diff-review session, snapshot cleared after accept-all/reset, or reject invoked after the review session ended).","commonSituations":"UI still showing the diff panel after the snapshot was consumed/reset; calling rejectModule on a manager instance that was never initialized with the original flow; race where the review session is torn down while a reject request is in flight.","solutions":["Only create/use the diff manager (and call rejectModule) within a review session that passes the original flow as beforeFlow.","Disable the reject/reject-all UI when beforeFlow is absent.","Re-open the review (recompute the diff with a fresh snapshot) if the session was already ended.","Guard calls: check the manager exposes a snapshot/hasBeforeFlow indicator first."],"exampleFix":"// before\nrejectAll()\n// after\nif (!diffManager.hasBeforeFlow) return\ndiffManager.rejectAll()","handlingStrategy":"validation","validationCode":"if (!diffManager.hasBeforeFlow()) return // no snapshot: nothing to reject","typeGuard":null,"tryCatchPattern":"try { rejectModule(id) } catch (e) { if ((e as Error).message.includes('beforeFlow')) reopenDiffReview(); else throw e }","preventionTips":["Instantiate the diff manager only within a review session that supplies the original flow.","Disable reject/reject-all controls once the snapshot is consumed or the session ends."],"tags":["flow-editor","diff","frontend","invalid-state"],"backgroundTag":"missing-snapshot-state","analyzedSha":"e474e8803ce2ff5c2df09a58dab51d45f5c922ca","analyzedAt":"2026-09-03T12:38:19.024Z","contentChangedAt":"2026-09-03T12:38:19.024Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}