wavetermdev/waveterm · error
cannot create directory %q: %w
Error message
cannot create directory %q: %w
What it means
RemoteFileTouchCommand wraps os.MkdirAll failure for the parent directory of the target file (created with 0755 before writing the file). Cause is permission denied, a path component being a file, or I/O errors.
Source
Thrown at pkg/wshrpc/wshremote/wshremote_file.go:424
Dir: computeDirPart(cleanedPath),
Name: filepath.Base(cleanedPath),
StatError: err.Error(),
SupportsMkdir: true,
}
continue
}
rtn[path] = *fileInfo
}
return rtn, nil
}
func (impl *ServerImpl) RemoteFileTouchCommand(ctx context.Context, path string) error {
cleanedPath := filepath.Clean(wavebase.ExpandHomeDirSafe(path))
if _, err := os.Stat(cleanedPath); err == nil {
return fmt.Errorf("file %q already exists", path)
}
if err := os.MkdirAll(filepath.Dir(cleanedPath), 0755); err != nil {
return fmt.Errorf("cannot create directory %q: %w", filepath.Dir(cleanedPath), err)
}
if err := os.WriteFile(cleanedPath, []byte{}, 0644); err != nil {
return fmt.Errorf("cannot create file %q: %w", cleanedPath, err)
}
return nil
}
func (impl *ServerImpl) RemoteFileMoveCommand(ctx context.Context, data wshrpc.CommandFileCopyData) error {
destUri := data.DestUri
srcUri := data.SrcUri
destConn, err := connparse.ParseURIAndReplaceCurrentHost(ctx, destUri)
if err != nil {
return fmt.Errorf("cannot parse destination URI %q: %w", srcUri, err)
}
destPathCleaned := filepath.Clean(wavebase.ExpandHomeDirSafe(destConn.Path))
_, err = os.Stat(destPathCleaned)
if err == nil {View on GitHub (pinned to a4447c1563)
Solutions
- Read the wrapped error to find which directory component failed.
- Ensure no ancestor path component is an existing file.
- Check write permission on the nearest existing ancestor.
- Create parent directories manually with correct permissions if 0755 is unsuitable.
Example fix
// before
wshclient.RemoteFileTouchCommand(ctx, "/srv/data/app/log.txt", nil)
// after
if _, err := wshclient.RemoteFileInfoCommand(ctx, "/srv/data/app", nil); err != nil {
return fmt.Errorf("parent dir unavailable: %w", err)
}
wshclient.RemoteFileTouchCommand(ctx, "/srv/data/app/log.txt", nil) Defensive patterns
Strategy: validation
Validate before calling
parent := filepath.Dir(path)
info, err := wshclient.RemoteFileInfoCommand(ctx, parent, nil)
if err == nil && !info.Dir { return fmt.Errorf("%s is a file, not a dir", parent) } Try / catch
err := wshclient.RemoteFileTouchCommand(ctx, path, nil)
if err != nil && strings.Contains(err.Error(), "cannot create directory") {
// inspect wrapped errno: EACCES / ENOTDIR
} Prevention
- Ensure no ancestor component is a regular file
- Verify write permission on the nearest existing ancestor
- Avoid read-only mounts for file creation
When it happens
Trigger: Touching a path whose parent directory cannot be created: ancestor is an existing regular file, write permission missing, or read-only filesystem.
Common situations: Creating files under read-only mounts; path like /home/user/file.txt/sub/deep where file.txt is a file; permission-restricted home directories.
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 create app bin directory: %w
- accessing file %s: %w
- getting absolute path for %s: %w
- reading directory %s: %w
- reading file %s: %w
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/fac4b6b37cdca8d7.
Report an issue: GitHub.