microsoft/typescript-go · error
failed to create profile directory: %w
Error message
failed to create profile directory: %w
What it means
StartCPUProfile wraps a failed os.MkdirAll on the requested profile directory. The directory is created lazily at start time; if any path component cannot be created (permission denied, a component is a file, read-only filesystem, path too long), the wrapped *PathError surfaces here and no profiling session begins.
Source
Thrown at internal/pprof/pprof.go:84
}
// CPUProfiler manages on-demand CPU profiling.
type CPUProfiler struct {
mu sync.Mutex
session *ProfileSession
}
// StartCPUProfile starts CPU profiling, writing to the specified directory when stopped.
func (c *CPUProfiler) StartCPUProfile(profileDir string) error {
c.mu.Lock()
defer c.mu.Unlock()
if c.session != nil {
return errors.New("CPU profiling already in progress")
}
if err := os.MkdirAll(profileDir, 0o755); err != nil {
return fmt.Errorf("failed to create profile directory: %w", err)
}
cpuProfilePath := filepath.Join(profileDir, fmt.Sprintf("%d-%d-cpuprofile.pb.gz", os.Getpid(), time.Now().UnixMilli()))
cpuFile, err := os.Create(cpuProfilePath)
if err != nil {
return fmt.Errorf("failed to create CPU profile file: %w", err)
}
if err := pprof.StartCPUProfile(cpuFile); err != nil {
cpuFile.Close()
os.Remove(cpuProfilePath)
return fmt.Errorf("failed to start CPU profile: %w", err)
}
c.session = &ProfileSession{
cpuFilePath: cpuProfilePath,
cpuFile: cpuFile,
logWriter: io.Discard,View on GitHub (pinned to 1bcfa18d79)
Solutions
- Point profileDir at a known-writable location (e.g. os.TempDir()-based or a mounted volume)
- Pre-create the directory in your deployment and grant write access to the server's user
- Check for regular-file path components shadowing the intended directory
Example fix
// before
err := profiler.StartCPUProfile("/var/run/prof") // root-owned
// after
err := profiler.StartCPUProfile(filepath.Join(os.TempDir(), "prof")) Defensive patterns
Strategy: validation
Validate before calling
if err := ensureWritableDir(profileDir); err != nil {
return err
}
func ensureWritableDir(dir string) error {
if err := os.MkdirAll(dir, 0o755); err != nil {
return err // surface before calling StartCPUProfile
}
probe := filepath.Join(dir, ".probe")
return os.WriteFile(probe, nil, 0o644)
} Try / catch
if err := profiler.StartCPUProfile(dir); err != nil {
if strings.Contains(err.Error(), "failed to create profile directory") {
return profiler.StartCPUProfile(filepath.Join(os.TempDir(), "prof")) // fallback location
}
return err
} Prevention
- Provision the profile directory with correct ownership at deploy time
- Pre-flight check writability before triggering profiling
- Avoid read-only mounts for profile output
When it happens
Trigger: Passing a profileDir under a read-only mount; a parent path component existing as a regular file; EACCES when the server runs as an unprivileged user against a root-owned directory; extremely long or invalid path strings; disk full on some filesystems.
Common situations: Containers with read-only rootfs and no writable volume mounted; profile dir configured under /var/run without permissions; typos creating unintended nested paths on restricted volumes.
Related errors
- failed to create CPU profile file: %w
- %w: failed to start CPU profile: %w
- %w: failed to save heap profile: %w
- error watching %s: %w
- error opening directory: %w
AI-assisted analysis of microsoft/typescript-go@1bcfa18d79 (2026-08-16).
Data as JSON: /api/errors/3ac89e692b9a66ea.
Report an issue: GitHub.