{"record":{"id":"33262ceff08c5f81","repo":"ahmetb/kubectx","slug":"failed-to-truncate-file-w","errorCode":null,"errorMessage":"failed to truncate file: %w","messagePattern":"failed to truncate file: %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/kubeconfig/kubeconfigloader.go","lineNumber":65,"sourceCode":"\t\tf, err := os.OpenFile(p, os.O_RDWR, 0)\n\t\tif err != nil {\n\t\t\tif os.IsNotExist(err) {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\treturn nil, fmt.Errorf(\"failed to open file %q: %w\", p, err)\n\t\t}\n\t\tfiles = append(files, &kubeconfigFile{File: f, path: p})\n\t}\n\tif len(files) == 0 {\n\t\treturn nil, fmt.Errorf(\"kubeconfig file not found: %w\",\n\t\t\t&os.PathError{Op: \"open\", Path: paths[0], Err: os.ErrNotExist})\n\t}\n\treturn files, nil\n}\n\nfunc (kf *kubeconfigFile) Reset() error {\n\tif err := kf.Truncate(0); err != nil {\n\t\treturn fmt.Errorf(\"failed to truncate file: %w\", err)\n\t}\n\tif _, err := kf.Seek(0, 0); err != nil {\n\t\treturn fmt.Errorf(\"failed to seek in file: %w\", err)\n\t}\n\treturn nil\n}\n\nfunc kubeconfigPaths() ([]string, error) {\n\t// KUBECONFIG env var\n\tif v := os.Getenv(\"KUBECONFIG\"); v != \"\" {\n\t\treturn filepath.SplitList(v), nil\n\t}\n\n\t// default path\n\thome := cmdutil.HomeDir()\n\tif home == \"\" {\n\t\treturn nil, errors.New(\"HOME or USERPROFILE environment variable not set\")\n\t}","sourceCodeStart":47,"sourceCodeEnd":83,"githubUrl":"https://github.com/ahmetb/kubectx/blob/12ad6fb22e8c546ee2b54e7de38aa51c906832f7/internal/kubeconfig/kubeconfigloader.go#L47-L83","documentation":"kubeconfigFile.Reset empties the underlying os.File via Truncate(0) so Save can rewrite it in place. This error wraps any Truncate failure with the original *os.PathError in %w, meaning the file could not be resized before rewriting.","triggerScenarios":"Calling Reset when the file cannot be truncated: the file was opened read-only, the filesystem is read-only, the file descriptor is already closed, or the OS returns EIO/EACCES on ftruncate.","commonSituations":"Filesystem remounted read-only after Load opened the file (disk-full failover); another component closed the shared *os.File first; editing a kubeconfig on a mounted CD/ISO or read-only volume.","solutions":["Inspect the wrapped *os.PathError for the errno and fix the filesystem condition (space, read-only flag)","Ensure the file was opened O_RDWR (the standard loader does this) and not closed elsewhere before Reset","Check permissions on the file and directory for the current user","Retry after the transient mount/disk condition is resolved"],"exampleFix":"// before\nf, _ := os.Open(p)          // read-only handle\nloader.Reset()              // truncate fails\n// after\nf, _ := os.OpenFile(p, os.O_RDWR, 0)\nloader.Reset()","handlingStrategy":"try-catch","validationCode":"// Go\n// Ensure writable and not on a read-only mount before mutating\nif fi, err := os.Stat(p); err != nil || fi.Mode().Perm()&0200 == 0 {\n    return fmt.Errorf(\"cannot reset %s: not writable\", p)\n}","typeGuard":"func isReadOnlyFSErr(err error) bool {\n    return errors.Is(err, syscall.EROFS) || errors.Is(err, os.ErrPermission)\n}","tryCatchPattern":"if err := kf.Reset(); err != nil {\n    var pe *fs.PathError\n    if errors.As(err, &pe) && errors.Is(pe.Err, os.ErrPermission) {\n        return fmt.Errorf(\"kubeconfig %s is not writable (chmod needed): %w\", pe.Path, err)\n    }\n    return err\n}","preventionTips":["Open kubeconfig files O_RDWR (as the standard loader does)","Do not edit kubeconfigs on read-only media or mounts","Serialize Reset/Save through one code path to avoid closed-handle errors","Re-check writable status after mount/disk changes"],"tags":["kubeconfig","file-io","go"],"backgroundTag":"file-truncate-failed","analyzedSha":"12ad6fb22e8c546ee2b54e7de38aa51c906832f7","analyzedAt":"2026-09-02T12:23:10.107Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T16:17:10.729Z"}