hasura/graphql-engine · error

download asset: %w

Error message

download asset: %w

What it means

ApplyUpdate wraps downloadAsset's failure when fetching the new release binary for version v (cli/update/update.go:146). The wrapped error is typically error 490 (io.Copy failure) or an earlier failure in creating/requesting the asset URL — the download step of the self-update could not complete.

Source

Thrown at cli/update/update.go:146

// ApplyUpdate downloads and applies the update indicated by version v.
func ApplyUpdate(v *semver.Version) error {
	var op errors.Op = "update.ApplyUpdate"
	// get the current executable
	exe, err := getExecutablePath()
	if err != nil {
		return errors.E(op, fmt.Errorf("find executable: %w", err))
	}

	// extract the filename and path
	exePath := filepath.Dir(exe)
	exeName := filepath.Base(exe)

	// download the new binary
	asset, err := downloadAsset(
		buildAssetURL(v.String()), "."+exeName+".new", exePath,
	)
	if err != nil {
		return errors.E(op, fmt.Errorf("download asset: %w", err))
	}

	// get the downloaded binary name and build the absolute path
	newExe := asset.Name()

	// build name and absolute path for saving old binary
	oldExeName := "." + exeName + ".old"
	oldExe := filepath.Join(exePath, oldExeName)

	// delete any existing old binary file - this is necessary on Windows for two reasons:
	// 1. after a successful update, Windows can't remove the .old file because the process is still running
	// 2. windows rename operations fail if the destination file already exists
	_ = os.Remove(oldExe)

	// rename the current binary as old binary
	err = os.Rename(exe, oldExe)
	if err != nil {
		return errors.E(op, fmt.Errorf("rename exe to old: %w", err))

View on GitHub (pinned to 724551b9ae)

Solutions

  1. Check write permissions on the executable's directory (chmod/chown or reinstall under a user-writable path).
  2. Verify the asset URL exists: curl -I the URL printed by buildAssetURL for your OS/arch.
  3. Retry after fixing network issues; clean leftover .<exe>.new files first.
  4. Confirm the version actually has published binaries for your platform.

Example fix

# before
$ cli update
# error: download asset: creating new binary file: permission denied

# after
$ sudo chown -R $(whoami) $(dirname $(which cli))
$ cli update
Defensive patterns

Strategy: validation

Validate before calling

dir := filepath.Dir(exe)
if info, err := os.Stat(dir); err != nil || !info.IsDir() {
    return fmt.Errorf("install dir missing: %s", dir)
}
f, err := os.CreateTemp(dir, ".wtest")
if err != nil { return fmt.Errorf("install dir not writable: %w", err) }
f.Close(); os.Remove(f.Name())

Try / catch

if err := update.ApplyUpdate(v); err != nil {
    if strings.Contains(err.Error(), "download asset") {
        os.Remove(filepath.Join(dir, "."+exeName+".new")) // cleanup
    }
    return err
}

Prevention

When it happens

Trigger: ApplyUpdate(v) where buildAssetURL(v.String()) is wrong (no such release asset for that version/OS/arch), the network fails, or the destination '.<exeName>.new' cannot be created in the executable's directory.

Common situations: Version v was a prerelease or asset names don't match the expected pattern; no write permission in /usr/local/bin (installed as root, run as user); proxy blocking the release download; disk full.

Related errors


AI-assisted analysis of hasura/graphql-engine@724551b9ae (2026-08-28). Data as JSON: /api/errors/1c1199272a1cd400. Report an issue: GitHub.