{"record":{"id":"656b47641ec69ceb","repo":"windmill-labs/windmill","slug":"yaml-sync-failed","errorCode":null,"errorMessage":"YAML sync failed","messagePattern":"YAML sync failed","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"frontend/src/lib/components/SuperadminSettings.svelte","lineNumber":72,"sourceCode":"\tfunction handleClose() {\n\t\tif (hasUnsavedChanges) {\n\t\t\tshowCloseConfirmModal = true\n\t\t} else {\n\t\t\tcloseDrawer()\n\t\t}\n\t}\n\n\t/** Catches click-away and escape closes from the Drawer/Disposable layer */\n\tfunction handleDrawerClose() {\n\t\tif (!bypassCloseCheck && hasUnsavedChanges) {\n\t\t\tdrawer?.openDrawer()\n\t\t\tshowCloseConfirmModal = true\n\t\t}\n\t\tbypassCloseCheck = false\n\t}\n\n\tasync function handleSave(): Promise<void> {\n\t\tif (!innerComponent?.syncBeforeDiff()) throw new Error('YAML sync failed')\n\t\tawait innerComponent?.saveSettings()\n\t}\n\n\tasync function handleSaveAndCloseDiff(): Promise<void> {\n\t\tawait handleSave()\n\t\tdiffDrawer?.closeDrawer()\n\t}\n\n\tfunction handleDiscard() {\n\t\tinnerComponent?.discardAll()\n\t}\n\n\tfunction handleReviewChanges() {\n\t\tif (!innerComponent?.syncBeforeDiff()) return\n\t\tdiffData = innerComponent?.buildFullDiff() ?? { original: '', modified: '' }\n\t\tdiffDrawer?.openDrawer()\n\t}\n</script>","sourceCodeStart":54,"sourceCodeEnd":90,"githubUrl":"https://github.com/windmill-labs/windmill/blob/e474e8803ce2ff5c2df09a58dab51d45f5c922ca/frontend/src/lib/components/SuperadminSettings.svelte#L54-L90","documentation":"handleSave in SuperadminSettings first asks the inner settings component to sync its form state into YAML (syncBeforeDiff) before persisting. If the inner component reports sync failure (falsy return), the save aborts with this Error so a stale-YAML write never happens silently.","triggerScenarios":"Clicking save (or Save-and-close-diff via handleSaveAndCloseDiff) when innerComponent?.syncBeforeDiff() returns false — the YAML editor content could not be reconciled with form state, typically due to invalid YAML or a desynchronized inner component ref.","commonSituations":"Hand-edited YAML in the diff drawer with syntax errors; switching between form and YAML views leaving stale state; innerComponent ref not yet mounted when save is triggered.","solutions":["Fix YAML syntax errors in the settings YAML editor so it parses and syncs","Reopen the settings/diff drawer to remount the inner component and retry","Check the browser console for the underlying sync error reported by the inner component","Save via the form (not the diff drawer) if the YAML state is unrecoverable"],"exampleFix":"// before\nif (!innerComponent?.syncBeforeDiff()) throw new Error('YAML sync failed')\n// after\nif (!innerComponent) throw new Error('Settings not loaded yet')\nif (!innerComponent.syncBeforeDiff()) {\n  sendUserToast('Could not sync YAML settings — check YAML syntax', true)\n  return\n}","handlingStrategy":"validation","validationCode":"// validate YAML parses before attempting save/sync\ntry { window.jsyaml.load(yamlText) } catch (e) { sendUserToast('Invalid YAML: ' + e.message, true) }","typeGuard":"function innerReady(c: unknown): c is { syncBeforeDiff(): boolean; saveSettings(): Promise<void> } {\n  return !!c && typeof (c as any).syncBeforeDiff === 'function'\n}","tryCatchPattern":"try {\n  await handleSave()\n} catch (e) {\n  if (e.message === 'YAML sync failed') {\n    sendUserToast('Fix YAML syntax before saving', true)\n  } else throw e\n}","preventionTips":["Validate YAML in the editor before opening the diff drawer","Let the inner component fully mount before enabling save buttons","Avoid hand-editing YAML unless it parses cleanly"],"tags":["yaml","settings","superadmin","sync"],"backgroundTag":"yaml-parse-failed","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"}