{"record":{"id":"2c9dd64671db4899","repo":"ahmetb/kubectx","slug":"failed-to-seek-in-file-w","errorCode":null,"errorMessage":"failed to seek in file: %w","messagePattern":"failed to seek in file: %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/kubeconfig/kubeconfigloader.go","lineNumber":68,"sourceCode":"\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}\n\treturn []string{filepath.Join(home, \".kube\", \"config\")}, nil\n}\n","sourceCodeStart":50,"sourceCodeEnd":86,"githubUrl":"https://github.com/ahmetb/kubectx/blob/12ad6fb22e8c546ee2b54e7de38aa51c906832f7/internal/kubeconfig/kubeconfigloader.go#L50-L86","documentation":"kubeconfigFile.Reset calls Truncate(0) then Seek(0, 0) to reposition the file offset at the start before rewriting. This error wraps any Seek failure; it happens after truncation, so the file may already be empty when this error surfaces.","triggerScenarios":"Calling Reset when the underlying file descriptor is invalid or already closed, causing os.File.Seek to fail (the underlying error is an *os.PathError with Op \"seek\").","commonSituations":"Double-close of the shared *os.File from concurrent code paths; using a file opened against a special file/device that does not support seeking; file descriptor corruption after an earlier I/O failure.","solutions":["Check the wrapped error — \"file already closed\" means another path closed the handle; remove the duplicate Close","Ensure Reset and Save run sequentially from one owner of the file handle, not concurrently","Verify the file is a regular file (special devices may not support seek)","Reload the kubeconfig from disk (construct a new loader) if the handle is in an unknown state"],"exampleFix":"// before\ngo k.Close()\nk.Save()   // handle closed mid-way; seek fails\n// after\nif err := k.Save(); err != nil { return err }\nif err := k.Close(); err != nil { return err }","handlingStrategy":"try-catch","validationCode":"// Go\n// Ensure the handle is still valid before Reset\nif _, err := kf.Seek(0, io.SeekCurrent); err != nil {\n    return fmt.Errorf(\"kubeconfig handle invalid: %w\", err)\n}","typeGuard":"func isClosedErr(err error) bool {\n    return errors.Is(err, os.ErrClosed)\n}","tryCatchPattern":"if err := kf.Reset(); err != nil {\n    if errors.Is(err, os.ErrClosed) {\n        return fmt.Errorf(\"kubeconfig file handle already closed — reload before saving: %w\", err)\n    }\n    return err\n}","preventionTips":["Define strict ownership: only one place closes the file, after all writes","Avoid concurrent goroutines sharing one kubeconfigFile handle","Reload from disk if handle state is uncertain instead of reusing it","Only use regular files for kubeconfigs"],"tags":["kubeconfig","file-io","go"],"backgroundTag":"file-seek-failed","analyzedSha":"12ad6fb22e8c546ee2b54e7de38aa51c906832f7","analyzedAt":"2026-09-02T12:23:10.107Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T16:17:10.729Z"}