hasura/graphql-engine · error
saving downloaded file: %w
Error message
saving downloaded file: %w
What it means
Raised by downloadAsset in the CLI self-updater when io.Copy fails while streaming a downloaded release asset to a newly created binary file (cli/update/update.go:94). It wraps the underlying I/O error, so the root cause may be a dropped network connection or a local disk problem. The partially written file is not cleaned up automatically by this error path.
Source
Thrown at cli/update/update.go:94
defer res.Body.Close()
if res.StatusCode != http.StatusOK {
return nil, errors.E(op, errors.E("could not find the release asset"))
}
asset, err := os.OpenFile(
filepath.Join(filePath, fileName),
os.O_CREATE|os.O_WRONLY|os.O_TRUNC,
0o755,
)
if err != nil {
return nil, errors.E(op, fmt.Errorf("creating new binary file: %w", err))
}
defer asset.Close()
_, err = io.Copy(asset, res.Body)
if err != nil {
return nil, errors.E(op, fmt.Errorf("saving downloaded file: %w", err))
}
return asset, nil
}
// HasUpdate tells us if there is a new stable or prerelease update available.
func HasUpdate(
currentVersion *semver.Version,
timeFile string,
) (bool, *semver.Version, bool, *semver.Version, error) {
var op errors.Op = "update.HasUpdate"
if timeFile != "" {
defer func() {
err := writeTimeToFile(timeFile, time.Now().UTC())
if err != nil {
fmt.Fprintln(os.Stderr, "failed writing last update check time: ", err)
}View on GitHub (pinned to 724551b9ae)
Solutions
- Check network stability and retry the update; the download is not resumable so a fresh attempt restarts it.
- Verify free disk space and write permissions in the executable's directory (df -h, ls -ld $(dirname $(which cli))).
- Manually delete any leftover .<exeName>.new partial file before retrying.
- If behind a proxy, ensure HTTPS streaming to the release URL is not being cut off.
Example fix
// before
asset, err := downloadAsset(url, ".cli.new", exePath)
if err != nil {
return err // partial file left behind
}
// after (caller-side hygiene)
asset, err := downloadAsset(url, ".cli.new", exePath)
if err != nil {
os.Remove(filepath.Join(exePath, ".cli.new")) // clean partial file
return err
} Defensive patterns
Strategy: retry
Validate before calling
if free, err := diskFree(exePath); err == nil && free < minAssetBytes {
return fmt.Errorf("insufficient disk space: %d bytes free", free)
} Try / catch
// Go: wrap and clean up partial file
asset, err := downloadAsset(url, name, dir)
if err != nil {
os.Remove(filepath.Join(dir, name))
return fmt.Errorf("download failed: %w", err)
} Prevention
- Keep sufficient free disk space in the install directory.
- Pre-check write permissions before starting an update.
- Retry once — mid-stream network drops are often transient.
When it happens
Trigger: Calling ApplyUpdate(v) (or the update command that calls it) where the HTTP response body is interrupted mid-download, the disk is full, or the target directory ('.<exeName>.new' next to the executable) becomes unwritable mid-copy.
Common situations: Flaky network dropping the GitHub release download halfway; disk full in the install directory (e.g. /usr/local/bin on a full partition); antivirus/lockers on Windows touching the .new file while it is written.
Related errors
- download asset: %w
- could not read archive: %w
- failed to copy directory tree as a fallback: %w
- get latest version: %w
- find executable: %w
AI-assisted analysis of hasura/graphql-engine@724551b9ae (2026-08-28).
Data as JSON: /api/errors/11ce35c897c822ac.
Report an issue: GitHub.