{"record":{"id":"5b30a2ea3fe0839d","repo":"kubernetes/kops","slug":"edit-cancelled-no-valid-changes-were-saved-5b30a2","errorCode":null,"errorMessage":"Edit cancelled: no valid changes were saved.","messagePattern":"Edit cancelled: no valid changes were saved\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"cmd/kops/edit_instancegroup.go","lineNumber":203,"sourceCode":"\t\tresults.header.writeTo(buf)\n\t\tresults.header.flush()\n\n\t\tif !containsError {\n\t\t\tbuf.Write(raw)\n\t\t} else {\n\t\t\tbuf.Write(stripComments(edited))\n\t\t}\n\n\t\t// launch the editor\n\t\teditedDiff := edited\n\t\tedited, file, err = editor.LaunchTempFile(fmt.Sprintf(\"%s-edit-\", filepath.Base(os.Args[0])), ext, buf)\n\t\tif err != nil {\n\t\t\treturn preservedFile(fmt.Errorf(\"error launching editor: %v\", err), results.file, out)\n\t\t}\n\n\t\tif containsError {\n\t\t\tif bytes.Equal(stripComments(editedDiff), stripComments(edited)) {\n\t\t\t\treturn preservedFile(fmt.Errorf(\"%s\", \"Edit cancelled: no valid changes were saved.\"), file, out)\n\t\t\t}\n\t\t}\n\n\t\tif len(results.file) > 0 {\n\t\t\ttry.RemoveFile(results.file)\n\t\t}\n\n\t\tif bytes.Equal(stripComments(raw), stripComments(edited)) {\n\t\t\ttry.RemoveFile(file)\n\t\t\tfmt.Fprintln(out, \"Edit cancelled: no changes made.\")\n\t\t\treturn nil\n\t\t}\n\n\t\tlines, err := hasLines(bytes.NewBuffer(edited))\n\t\tif err != nil {\n\t\t\treturn preservedFile(err, file, out)\n\t\t}\n\t\tif !lines {","sourceCodeStart":185,"sourceCodeEnd":221,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/cmd/kops/edit_instancegroup.go#L185-L221","documentation":"When the previous save produced a validation error (containsError) and the user re-saves the editor with no effective changes after comment stripping, kops aborts with \"Edit cancelled: no valid changes were saved.\". It prevents silently re-submitting identical invalid content, and preserves the temp file so the user can keep editing.","triggerScenarios":"In `kops edit instancegroup`, after a failed validation round, saving the editor without modifying any non-comment content — stripComments(editedDiff) equals stripComments(edited).","commonSituations":"User opens the editor during an error round-trip, changes nothing, and hits :wq expecting the loop to end; an editor auto-format feature reflows whitespace/comments only.","solutions":["Actually fix the validation problem reported before the edit (the prior error message states what was invalid)","If you want to abandon the edit, remove/blank the substantive fields so content differs, or Ctrl-C out of the command","Edit the preserved temp file (path is printed) and re-apply, or use `kops replace -f file.yaml` after fixing offline"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"before := stripComments(buf.Bytes())\n// after editing, before saving, confirm substantive content changed\nif bytes.Equal(before, stripComments(edited)) {\n    return errors.New(\"no substantive changes made; fix the reported validation error or abort\")\n}","typeGuard":null,"tryCatchPattern":"if err := runEdit(); err != nil {\n    if strings.Contains(err.Error(), \"Edit cancelled\") {\n        // user made no changes in an error round; surface the original validation error\n    }\n}","preventionTips":["Read the validation error printed before the editor opens and fix that specific field","Don't save an unchanged buffer during error round-trips; Ctrl-C to abort instead","Disable editor auto-formatting that only changes whitespace/comments","Use `kops replace -f` offline where you control exactly what changes"],"tags":["cli","editor","validation"],"backgroundTag":"edit-cancelled-no-changes","analyzedSha":"4c8573c808a73d578c5eadc86d410646ea0b0d73","analyzedAt":"2026-09-05T04:13:19.212Z","contentChangedAt":"2026-09-05T04:13:19.212Z","schemaVersion":2},"datasetVersion":"2026-09-12T12:17:11.808Z"}