microsoft/typescript-go · error

failed to create heap profile file: %w

Error message

failed to create heap profile file: %w

What it means

SaveHeapProfile could not os.Create the generated heap profile file (<pid>-<millis>-heapprofile.pb.gz) inside an existing directory. Pure file-level failure after successful mkdir: permission mismatch, ENOSPC, filesystem I/O error, or policy denial. The heap snapshot is not taken.

Source

Thrown at internal/pprof/pprof.go:132

	}

	filePath := c.session.cpuFilePath
	c.session.Stop()
	c.session = nil

	return filePath, nil
}

// SaveHeapProfile saves a heap profile to the specified directory.
func SaveHeapProfile(profileDir string) (string, error) {
	if err := os.MkdirAll(profileDir, 0o755); err != nil {
		return "", fmt.Errorf("failed to create profile directory: %w", err)
	}

	heapProfilePath := filepath.Join(profileDir, fmt.Sprintf("%d-%d-heapprofile.pb.gz", os.Getpid(), time.Now().UnixMilli()))
	heapFile, err := os.Create(heapProfilePath)
	if err != nil {
		return "", fmt.Errorf("failed to create heap profile file: %w", err)
	}
	defer heapFile.Close()

	runtime.GC()
	if err := pprof.Lookup("heap").WriteTo(heapFile, 0); err != nil {
		os.Remove(heapProfilePath)
		return "", fmt.Errorf("failed to write heap profile: %w", err)
	}

	return heapProfilePath, nil
}

// SaveAllocProfile saves an allocation profile to the specified directory.
func SaveAllocProfile(profileDir string) (string, error) {
	if err := os.MkdirAll(profileDir, 0o755); err != nil {
		return "", fmt.Errorf("failed to create profile directory: %w", err)
	}

View on GitHub (pinned to 1bcfa18d79)

Solutions

  1. Free space or redirect profileDir to a volume with headroom
  2. Run a write probe into the directory before triggering the dump
  3. Fix directory ownership/permissions for the server user
Defensive patterns

Strategy: try-catch

Validate before calling

if writable, err := canCreateFile(profileDir); !writable {
	return fmt.Errorf("heap dump target not writable: %w", err)
}

func canCreateFile(dir string) (bool, error) {
	f, err := os.CreateTemp(dir, "probe-*")
	if err != nil { return false, err }
	f.Close()
	return true, os.Remove(f.Name())
}

Try / catch

if _, err := pprof.SaveHeapProfile(dir); err != nil {
	var perr *fs.PathError
	if errors.As(err, &perr) && (perr.Err == syscall.EACCES || perr.Err == syscall.ENOSPC) {
		return pprof.SaveHeapProfile(os.TempDir())
	}
	return "", err
}

Prevention

When it happens

Trigger: Sticky-bit directory owned by another user; disk full at the moment of the dump; network filesystem rejecting the create; security policy blocking gz writes in that path.

Common situations: Memory-incident automation firing when the disk is already full (correlated events); shared /tmp with restrictive modes; container security profiles.

Related errors


AI-assisted analysis of microsoft/typescript-go@1bcfa18d79 (2026-08-16). Data as JSON: /api/errors/e52ad9bf2fa3f24c. Report an issue: GitHub.