henrygd/beszel · error

open tmp: %w

Error message

open tmp: %w

What it means

Thrown by downloadFile when os.OpenFile fails to create/truncate the temporary file dest+".tmp" for writing the download. It wraps the OS-level error (permission denied, read-only filesystem, invalid path). Failure happens after a successful HTTP response.

Source

Thrown at agent/tools/fetchsmartctl/main.go:71

	if err != nil {
		return fmt.Errorf("new request: %w", err)
	}
	req.Header.Set("User-Agent", "beszel-fetchsmartctl/1.0")

	resp, err := client.Do(req)
	if err != nil {
		return fmt.Errorf("http get: %w", err)
	}
	defer resp.Body.Close()

	if resp.StatusCode < 200 || resp.StatusCode >= 300 {
		return fmt.Errorf("unexpected HTTP status: %s", resp.Status)
	}

	tmp := dest + ".tmp"
	f, err := os.OpenFile(tmp, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0o644)
	if err != nil {
		return fmt.Errorf("open tmp: %w", err)
	}

	// Determine hash algorithm based on length (SHA1=40, SHA256=64)
	var hasher hash.Hash
	if shaHex := strings.TrimSpace(shaHex); shaHex != "" {
		cleanSha := strings.ToLower(strings.ReplaceAll(shaHex, " ", ""))
		switch len(cleanSha) {
		case 40:
			hasher = sha1.New()
		case 64:
			hasher = sha256.New()
		default:
			f.Close()
			os.Remove(tmp)
			return fmt.Errorf("unsupported hash length: %d (expected 40 for SHA1 or 64 for SHA256)", len(cleanSha))
		}
	}

View on GitHub (pinned to b38fb7dafa)

Solutions

  1. Check the wrapped %w OS error for the exact reason
  2. Verify the destination directory is writable and the tmp path isn't an existing directory
  3. Free disk space / raise quota if ENOSPC
  4. Run in a writable working directory (copy the tool's output outside a read-only tree)
Defensive patterns

Strategy: validation

Validate before calling

tmpPath := dest + ".tmp"
if info, err := os.Stat(tmpPath); err == nil && info.IsDir() {
	return fmt.Errorf("%s is a directory", tmpPath)
}
if f, err := os.OpenFile(tmpPath, os.O_CREATE|os.O_WRONLY, 0o644); err != nil {
	return err
} else {
	f.Close()
	os.Remove(tmpPath)
}

Try / catch

if err := downloadFile(url, dest, sha); err != nil {
	var perr *fs.PathError
	if errors.As(err, &perr) && perr.Op == "open" {
		fmt.Printf("cannot write %s: %v — check permissions/space\n", perr.Path, perr.Err)
	}
	os.Exit(1)
}

Prevention

When it happens

Trigger: Opening the .tmp file fails because the destination directory isn't writable, the tmp path is a directory, or the filesystem rejects O_CREATE/O_TRUNC.

Common situations: Read-only CI checkout; destination name collides with an existing directory; disk quota exceeded; SELinux/AppArmor policy denying writes.

Related errors


AI-assisted analysis of henrygd/beszel@b38fb7dafa (2026-08-31). Data as JSON: /api/errors/05f67992d4f9f576. Report an issue: GitHub.