{"record":{"id":"3ac89e692b9a66ea","repo":"microsoft/typescript-go","slug":"failed-to-create-profile-directory-w","errorCode":null,"errorMessage":"failed to create profile directory: %w","messagePattern":"failed to create profile directory: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/pprof/pprof.go","lineNumber":84,"sourceCode":"}\n\n// CPUProfiler manages on-demand CPU profiling.\ntype CPUProfiler struct {\n\tmu      sync.Mutex\n\tsession *ProfileSession\n}\n\n// StartCPUProfile starts CPU profiling, writing to the specified directory when stopped.\nfunc (c *CPUProfiler) StartCPUProfile(profileDir string) error {\n\tc.mu.Lock()\n\tdefer c.mu.Unlock()\n\n\tif c.session != nil {\n\t\treturn errors.New(\"CPU profiling already in progress\")\n\t}\n\n\tif err := os.MkdirAll(profileDir, 0o755); err != nil {\n\t\treturn fmt.Errorf(\"failed to create profile directory: %w\", err)\n\t}\n\n\tcpuProfilePath := filepath.Join(profileDir, fmt.Sprintf(\"%d-%d-cpuprofile.pb.gz\", os.Getpid(), time.Now().UnixMilli()))\n\tcpuFile, err := os.Create(cpuProfilePath)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to create CPU profile file: %w\", err)\n\t}\n\n\tif err := pprof.StartCPUProfile(cpuFile); err != nil {\n\t\tcpuFile.Close()\n\t\tos.Remove(cpuProfilePath)\n\t\treturn fmt.Errorf(\"failed to start CPU profile: %w\", err)\n\t}\n\n\tc.session = &ProfileSession{\n\t\tcpuFilePath: cpuProfilePath,\n\t\tcpuFile:     cpuFile,\n\t\tlogWriter:   io.Discard,","sourceCodeStart":66,"sourceCodeEnd":102,"githubUrl":"https://github.com/microsoft/typescript-go/blob/1bcfa18d79a3be41772223d5c05dfe4480e614ff/internal/pprof/pprof.go#L66-L102","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nerr := profiler.StartCPUProfile(\"/var/run/prof\") // root-owned\n\n// after\nerr := profiler.StartCPUProfile(filepath.Join(os.TempDir(), \"prof\"))","handlingStrategy":"validation","validationCode":"if err := ensureWritableDir(profileDir); err != nil {\n\treturn err\n}\n\nfunc ensureWritableDir(dir string) error {\n\tif err := os.MkdirAll(dir, 0o755); err != nil {\n\t\treturn err // surface before calling StartCPUProfile\n\t}\n\tprobe := filepath.Join(dir, \".probe\")\n\treturn os.WriteFile(probe, nil, 0o644)\n}","typeGuard":null,"tryCatchPattern":"if err := profiler.StartCPUProfile(dir); err != nil {\n\tif strings.Contains(err.Error(), \"failed to create profile directory\") {\n\t\treturn profiler.StartCPUProfile(filepath.Join(os.TempDir(), \"prof\")) // fallback location\n\t}\n\treturn err\n}","preventionTips":["Provision the profile directory with correct ownership at deploy time","Pre-flight check writability before triggering profiling","Avoid read-only mounts for profile output"],"tags":["pprof","filesystem","permissions","profiling"],"backgroundTag":null,"analyzedSha":"1bcfa18d79a3be41772223d5c05dfe4480e614ff","analyzedAt":"2026-08-16T02:12:00.115Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}