{"record":{"id":"f954f473239c815f","repo":"ahmetb/kubectx","slug":"failed-to-close-encoder-for-file-d-w","errorCode":null,"errorMessage":"failed to close encoder for file %d: %w","messagePattern":"failed to close encoder for file (.+?): %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/kubeconfig/kubeconfig.go","lineNumber":214,"sourceCode":"\tseqNode := &yaml.Node{Kind: yaml.SequenceNode, Tag: \"!!seq\"}\n\tfor _, elem := range elements {\n\t\tseqNode.Content = append(seqNode.Content, elem.YNode())\n\t}\n\treturn yaml.NewRNode(seqNode), nil\n}\n\nfunc (k *Kubeconfig) Save() error {\n\tfor i := range k.files {\n\t\tif err := k.files[i].f.Reset(); err != nil {\n\t\t\treturn fmt.Errorf(\"failed to reset file %d: %w\", i, err)\n\t\t}\n\t\tenc := yaml.NewEncoder(k.files[i].f)\n\t\tenc.SetIndent(0)\n\t\tif err := enc.Encode(k.files[i].config.YNode()); err != nil {\n\t\t\treturn fmt.Errorf(\"failed to encode file %d: %w\", i, err)\n\t\t}\n\t\tif err := enc.Close(); err != nil {\n\t\t\treturn fmt.Errorf(\"failed to close encoder for file %d: %w\", i, err)\n\t\t}\n\t}\n\treturn nil\n}\n","sourceCodeStart":196,"sourceCodeEnd":219,"githubUrl":"https://github.com/ahmetb/kubectx/blob/12ad6fb22e8c546ee2b54e7de38aa51c906832f7/internal/kubeconfig/kubeconfig.go#L196-L219","documentation":"internal/kubeconfig.Kubeconfig.Save writes every tracked kubeconfig file through a yaml.Encoder; after encoding it calls enc.Close() to flush buffered output. This error wraps any failure from that Close call, meaning the YAML document was encoded in memory but the bytes may not have been fully flushed to the underlying file. The wrapped error (%w) carries the actual I/O cause (usually from the underlying os.File flush path).","triggerScenarios":"Calling Save (directly or via switchNamespace/clearNamespace) when the yaml.Encoder's Close fails, typically because the underlying os.File write errors at flush time: disk full, file closed elsewhere, permission change mid-write, or I/O error on the output stream.","commonSituations":"Disk quota exceeded while saving a modified ~/.kube/config; read-only filesystem remounted after the file was opened; an underlying file that was closed by another code path before Save; NFS/network filesystem transient errors.","solutions":["Check the wrapped error for the root cause (disk full, EROFS, EIO) and free space / fix filesystem access","Verify no other goroutine or code path closes the same file before Save is called","Check write permissions on the kubeconfig file and parent directory","Re-run Save after fixing the environment; the error is transient unless the filesystem is broken"],"exampleFix":"// before\nif err := k.files[i].f.Close(); err != nil { log.Println(err) }\nk.Save()\n// after\nif err := k.Save(); err != nil {\n    var pe *fs.PathError\n    if errors.As(err, &pe) {\n        log.Fatalf(\"save failed on %s: %v\", pe.Path, pe.Err)\n    }\n}","handlingStrategy":"try-catch","validationCode":"// Go\n// Before Save, ensure the target files are writable and space exists\nfor _, p := range paths {\n    fi, err := os.Stat(p)\n    if err != nil || fi.Mode().Perm()&0200 == 0 {\n        return fmt.Errorf(\"kubeconfig %s not writable\", p)\n    }\n}","typeGuard":"func asPathError(err error) (*fs.PathError, bool) {\n    var pe *fs.PathError\n    if errors.As(err, &pe) { return pe, true }\n    return nil, false\n}","tryCatchPattern":"if err := k.Save(); err != nil {\n    var pe *fs.PathError\n    if errors.As(err, &pe) {\n        log.Printf(\"save failed (%s): %v\", pe.Path, pe.Err)\n    }\n    return err\n}","preventionTips":["Check disk space and write permissions on kubeconfig files before modifying them","Keep a single owner of the file handle; never close the underlying file outside Save","Treat wrapped errors with errors.As(*fs.PathError) to get path and errno","Back up the kubeconfig before bulk namespace switches"],"tags":["kubeconfig","yaml","io","go"],"backgroundTag":"encoder-close-failed","analyzedSha":"12ad6fb22e8c546ee2b54e7de38aa51c906832f7","analyzedAt":"2026-09-02T12:23:10.107Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T16:17:10.729Z"}