{"record":{"id":"78235d57abada85c","repo":"wavetermdev/waveterm","slug":"failed-to-create-socket-directory-w","errorCode":null,"errorMessage":"failed to create socket directory: %w","messagePattern":"failed to create socket directory: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/jobmanager/jobmanager.go","lineNumber":383,"sourceCode":"\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to attach stream writer: %w\", err)\n\t}\n\n\terr = jm.StreamManager.SetRwndSize(int(jm.pendingStreamMeta.RWnd))\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to set rwnd size: %w\", err)\n\t}\n\n\tlog.Printf(\"StartStream: streamid=%s rwnd=%d streaming started\\n\", jm.pendingStreamMeta.Id, jm.pendingStreamMeta.RWnd)\n\tjm.pendingStreamMeta = nil\n\treturn nil\n}\n\nfunc MakeJobDomainSocket(clientId string, jobId string) error {\n\tsocketDir := filepath.Join(\"/tmp\", fmt.Sprintf(\"waveterm-%d\", os.Getuid()))\n\terr := os.MkdirAll(socketDir, 0700)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to create socket directory: %w\", err)\n\t}\n\n\tsocketPath := wavebase.GetRemoteJobSocketPath(jobId)\n\n\tos.Remove(socketPath)\n\n\tlistener, err := net.Listen(\"unix\", socketPath)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to listen on domain socket: %w\", err)\n\t}\n\n\tgo func() {\n\t\tdefer func() {\n\t\t\tpanichandler.PanicHandler(\"MakeJobDomainSocket:accept\", recover())\n\t\t\tlistener.Close()\n\t\t\tos.Remove(socketPath)\n\t\t}()\n\t\tfor {","sourceCodeStart":365,"sourceCodeEnd":401,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/pkg/jobmanager/jobmanager.go#L365-L401","documentation":"MakeJobDomainSocket creates the per-user socket directory /tmp/waveterm-<uid> with os.MkdirAll(0700) before binding the job's domain socket. This error wraps any MkdirAll failure. It almost always means a filesystem/permission problem on /tmp rather than a bug in the caller.","triggerScenarios":"os.MkdirAll(\"/tmp/waveterm-<uid>\", 0700) fails because /tmp is not writable, the path exists as a regular file, the filesystem is full or read-only, or a path component denies traversal.","commonSituations":"Container with read-only /tmp; sticky-bit /tmp with restrictive mount options; leftover regular file named waveterm-<uid> in /tmp; disk-full (ENOSPC) on tmpfs; SELinux/AppArmor denial.","solutions":["Check whether /tmp/waveterm-<uid> exists as a file and remove it: ls -la /tmp | grep waveterm","Verify /tmp is writable for the running uid; free space if ENOSPC","Set TMPDIR to a writable directory if the environment restricts /tmp (if the code honors it; otherwise fix mounts)","Inspect the wrapped error for EACCES/EROFS/ENOSPC and fix the corresponding mount/permission"],"exampleFix":"// before\nif err := os.MkdirAll(socketDir, 0700); err != nil {\n    return fmt.Errorf(\"failed to create socket directory: %w\", err)\n}\n// after\nif err := os.MkdirAll(socketDir, 0700); err != nil {\n    if fi, serr := os.Lstat(socketDir); serr == nil && !fi.IsDir() {\n        if rmErr := os.Remove(socketDir); rmErr == nil {\n            return MakeJobDomainSocket(clientId, jobId)\n        }\n    }\n    return fmt.Errorf(\"failed to create socket directory %s: %w\", socketDir, err)\n}","handlingStrategy":"try-catch","validationCode":"sd := fmt.Sprintf(\"/tmp/waveterm-%d\", os.Getuid())\nif fi, err := os.Stat(\"/tmp\"); err != nil || !fi.IsDir() {\n    return fmt.Errorf(\"/tmp unavailable\")\n}\nif fi, err := os.Lstat(sd); err == nil && !fi.IsDir() {\n    return fmt.Errorf(\"%s exists and is not a directory\", sd)\n}","typeGuard":null,"tryCatchPattern":"if err := MakeJobDomainSocket(clientId, jobId); err != nil {\n    if strings.HasPrefix(err.Error(), \"failed to create socket directory\") {\n        log.Printf(\"socket dir error: %v\", errors.Unwrap(err))\n        // check /tmp writability, ENOSPC, or blocking file\n    }\n    return err\n}","preventionTips":["Pre-flight check that /tmp is writable for the current uid","Clean stale /tmp/waveterm-<uid> entries (especially files masquerading as directories) at startup","Monitor tmpfs/disk space in containers","Inspect the wrapped errno (EACCES/EROFS/ENOSPC) to target the right fix"],"tags":["go","filesystem","unix-socket","permissions","tmpdir"],"backgroundTag":"mkdir-permission-denied","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}