wavetermdev/waveterm · error
failed to create log directory: %w
Error message
failed to create log directory: %w
What it means
daemonize creates the directory for the job log file (wavebase.GetRemoteJobFilePath(jobId, "log")) with os.MkdirAll(0700) before opening it. This error wraps that MkdirAll failure. It means the job-control directory under the Wave home/sessions tree could not be created, typically a permissions or disk problem.
Source
Thrown at pkg/jobmanager/jobmanager_unix.go:40
if err != nil {
return fmt.Errorf("failed to setsid: %w", err)
}
devNull, err := os.OpenFile("/dev/null", os.O_RDWR, 0)
if err != nil {
return fmt.Errorf("failed to open /dev/null: %w", err)
}
err = unix.Dup2(int(devNull.Fd()), int(os.Stdin.Fd()))
if err != nil {
return fmt.Errorf("failed to dup2 stdin: %w", err)
}
devNull.Close()
logPath := wavebase.GetRemoteJobFilePath(jobId, "log")
logDir := filepath.Dir(logPath)
err = os.MkdirAll(logDir, 0700)
if err != nil {
return fmt.Errorf("failed to create log directory: %w", err)
}
logFile, err := os.OpenFile(logPath, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0600)
if err != nil {
return fmt.Errorf("failed to open log file: %w", err)
}
err = unix.Dup2(int(logFile.Fd()), int(os.Stdout.Fd()))
if err != nil {
return fmt.Errorf("failed to dup2 stdout: %w", err)
}
err = unix.Dup2(int(logFile.Fd()), int(os.Stderr.Fd()))
if err != nil {
return fmt.Errorf("failed to dup2 stderr: %w", err)
}
log.SetOutput(logFile)
log.Printf("job manager daemonized, logging to %s\n", logPath)
log.Printf("job owner clientid: %s\n", clientId)View on GitHub (pinned to a4447c1563)
Solutions
- Check the wrapped errno and verify the log directory path is writable by the current uid
- Confirm the Wave data directory (and any configured override) exists and is not read-only
- Free disk space if the error is ENOSPC
- Remove any regular file occupying the logDir path so MkdirAll can create the directory
Example fix
// before
err = os.MkdirAll(logDir, 0700)
if err != nil {
return fmt.Errorf("failed to create log directory: %w", err)
}
// after
if err := os.MkdirAll(logDir, 0700); err != nil {
if fi, serr := os.Lstat(logDir); serr == nil && !fi.IsDir() {
if rmErr := os.Remove(logDir); rmErr != nil {
return fmt.Errorf("log dir path blocked by file: %w", rmErr)
}
err = os.MkdirAll(logDir, 0700)
}
if err != nil {
return fmt.Errorf("failed to create log directory %s: %w", logDir, err)
}
} Defensive patterns
Strategy: try-catch
Validate before calling
logPath := wavebase.GetRemoteJobFilePath(jobId, "log")
logDir := filepath.Dir(logPath)
if fi, err := os.Lstat(logDir); err == nil && !fi.IsDir() {
return fmt.Errorf("%s exists and is not a directory", logDir)
} Try / catch
if err := daemonize(clientId, jobId); err != nil {
if strings.Contains(err.Error(), "failed to create log directory") {
log.Printf("log dir error: %v", errors.Unwrap(err))
// check home/data dir writability, ENOSPC, blocking file
}
return err
} Prevention
- Verify the Wave data/home directory is writable by the job uid
- Check disk space and quotas on the data volume
- Remove stray regular files occupying expected directory paths
- Validate any env override controlling the data root points to a writable location
When it happens
Trigger: os.MkdirAll(logDir, 0700) fails because the Wave data directory is unwritable, a path component exists as a regular file, the disk is full, or the home directory is read-only/not mounted.
Common situations: Read-only home directory or NFS mount without write access; WAVE_HOME/env override pointing at an unwritable path; leftover file where a directory is expected; ENOSPC on the data volume; SELinux denials on the home tree.
Understand the failure class
Background: mkdir permission denied (EACCES): failed to create directory errors explained — this error's family across 32 libraries.
Related errors
- failed to open log file: %w
- failed to create backup directory: %w
- failed to create socket directory: %w
- failed to open /dev/null: %w
- failed to read directory: %w
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/53a370aafb271331.
Report an issue: GitHub.