plandex-ai/plandex · error

failed to create temporary file: %w

Error message

failed to create temporary file: %w

What it means

After fetching the release archive, doUpgrade creates a temp file with os.CreateTemp to hold the downloaded tar.gz. If the OS refuses to create the file, the error is wrapped as 'failed to create temporary file: %w'. This is an environment/permissions problem on the local filesystem, not a network issue.

Source

Thrown at app/cli/upgrade.go:113

		}
	}
}

func doUpgrade(version string) error {
	tag := fmt.Sprintf("cli/v%s", version)
	escapedTag := url.QueryEscape(tag)

	downloadURL := fmt.Sprintf("https://github.com/plandex-ai/plandex/releases/download/%s/plandex_%s_%s_%s.tar.gz", escapedTag, version, runtime.GOOS, runtime.GOARCH)
	resp, err := http.Get(downloadURL)
	if err != nil {
		return fmt.Errorf("failed to download the update: %w", err)
	}
	defer resp.Body.Close()

	// Create a temporary file to save the downloaded archive
	tempFile, err := os.CreateTemp("", "*.tar.gz")
	if err != nil {
		return fmt.Errorf("failed to create temporary file: %w", err)
	}
	defer os.Remove(tempFile.Name()) // Clean up file afterwards

	// Copy the response body to the temporary file
	_, err = io.Copy(tempFile, resp.Body)
	if err != nil {
		return fmt.Errorf("failed to save the downloaded archive: %w", err)
	}

	_, err = tempFile.Seek(0, 0)
	if err != nil {
		return fmt.Errorf("failed to seek in temporary file: %w", err)
	}

	// Now, extract the binary from the tempFile
	gzr, err := gzip.NewReader(tempFile)
	if err != nil {
		return fmt.Errorf("failed to create gzip reader: %w", err)

View on GitHub (pinned to e2d772072e)

Solutions

  1. Check TMPDIR points to a writable directory; unset or fix it if wrong.
  2. Free disk space on the temp filesystem (df /tmp).
  3. Set TMPDIR to a writable path, e.g. export TMPDIR=$HOME/tmp.
  4. Check mount options/permissions on /tmp (chmod 1777) or SELinux denials.

Example fix

// before
export TMPDIR=/nonexistent
// after
export TMPDIR=$HOME/tmp && mkdir -p $HOME/tmp
Defensive patterns

Strategy: validation

Validate before calling

tmpDir := os.TempDir()
fi, err := os.Stat(tmpDir)
if err != nil || !fi.IsDir() {
	return fmt.Errorf("temp dir %s unusable", tmpDir)
}
probe, err := os.CreateTemp(tmpDir, ".probe")
if err != nil {
	return fmt.Errorf("temp dir not writable: %w", err)
}
probe.Close()
os.Remove(probe.Name())

Try / catch

tempFile, err := os.CreateTemp("", "*.tar.gz")
if err != nil {
	return fmt.Errorf("failed to create temporary file: %w (TMPDIR=%s)", err, os.TempDir())
}

Prevention

When it happens

Trigger: os.CreateTemp("", "*.tar.gz") fails because TMPDIR points to a non-writable or nonexistent directory, the disk is full, or strict permissions/noexec tmpfs settings block file creation.

Common situations: Read-only /tmp (container with read-only rootfs), TMPDIR set to a path the user can't write, disk quota exhausted, SELinux/AppArmor denial.

Related errors


AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05). Data as JSON: /api/errors/6d11421b481b9b99. Report an issue: GitHub.