{"record":{"id":"c6cd936939a7d44e","repo":"cli/cli","slug":"failed-to-close-file-w","errorCode":null,"errorMessage":"failed to close file: %w","messagePattern":"failed to close file: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/cmd/copilot/copilot.go","lineNumber":461,"sourceCode":"\t\t\t\treturn fmt.Errorf(\"failed to create parent directory: %w\", err)\n\t\t\t}\n\t\t\tif err := extractFile(target, os.FileMode(header.Mode)&0777, tr); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t}\n\treturn nil\n}\n\n// extractFile creates a file at target with the given mode and copies content from r.\nfunc extractFile(target string, mode os.FileMode, r io.Reader) (err error) {\n\tout, err := os.OpenFile(target, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, mode)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to create file: %w\", err)\n\t}\n\tdefer func() {\n\t\tif cerr := out.Close(); err == nil && cerr != nil {\n\t\t\terr = fmt.Errorf(\"failed to close file: %w\", cerr)\n\t\t}\n\t}()\n\tif _, err := io.Copy(out, r); err != nil {\n\t\treturn fmt.Errorf(\"failed to write file: %w\", err)\n\t}\n\treturn nil\n}\n\nfunc removeCopilot(installDir string) error {\n\tif _, err := os.Stat(installDir); os.IsNotExist(err) {\n\t\treturn fmt.Errorf(\"failed to remove Copilot CLI: Copilot CLI not installed through `gh`\")\n\t}\n\n\tif err := os.RemoveAll(installDir); err != nil {\n\t\treturn fmt.Errorf(\"failed to remove Copilot CLI: %w\", err)\n\t}\n\n\treturn nil","sourceCodeStart":443,"sourceCodeEnd":479,"githubUrl":"https://github.com/cli/cli/blob/0eeec0b92edbe70199f9768522f831d3534f41ad/pkg/cmd/copilot/copilot.go#L443-L479","documentation":"The deferred close in extractFile found that out.Close() failed while the copy itself succeeded (the guard only fires when err == nil). Closing a written file can fail when buffered data cannot be flushed, so the file on disk may be incomplete even though no earlier error was reported.","triggerScenarios":"os.File.Close returning an error after io.Copy succeeded: typically ENOSPC (disk filled between copy buffering and flush) or an NFS/network filesystem failing to commit dirty pages.","commonSituations":"Disk-full during copilot agent installation; flaky network-mounted home directories; container overlay filesystems under space pressure.","solutions":["Check disk space on the destination volume (df -h) and free space","Retry the install after freeing space - treat a close failure as a possibly-corrupt file","If on NFS/network storage, verify mount health and retry","Consider a local install directory"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err := extractFile(target, mode, r); err != nil {\n    if strings.Contains(err.Error(), \"failed to close file\") {\n        // close failure after successful copy usually means disk-full flush failure;\n        // the file may be corrupt, so remove it\n        _ = os.Remove(target)\n        return fmt.Errorf(\"possible incomplete write (disk full?): %w\", err)\n    }\n    return err\n}","preventionTips":["Check free disk space before starting large extractions","Treat close errors as write failures, never as success","Use the same deferred-close-and-propagate pattern extractFile uses in your own code"],"tags":["copilot","filesystem","disk-full","extract"],"backgroundTag":null,"analyzedSha":"0eeec0b92edbe70199f9768522f831d3534f41ad","analyzedAt":"2026-08-15T12:31:05.478Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}