hasura/graphql-engine · error
failed to ensure create directory %q: %w
Error message
failed to ensure create directory %q: %w
What it means
ensureDirs runs os.MkdirAll(path, 0o755) for each path passed to it (called from Prepare before plugin install). If any MkdirAll fails — permission denied, a path component is an existing file, or an I/O error — this error wraps the failing path and the underlying OS error.
Source
Thrown at cli/plugins/util.go:51
// windowsForbidden is taken from https://docs.microsoft.com/en-us/windows/desktop/FileIO/naming-a-file
windowsForbidden = []string{
"CON", "PRN", "AUX", "NUL", "COM1", "COM2",
"COM3", "COM4", "COM5", "COM6", "COM7", "COM8", "COM9", "LPT1", "LPT2",
"LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9",
}
)
func isValidSHA256(s string) bool { return validSHA256.MatchString(s) }
// ensureDirs makes sure the paths created.
func ensureDirs(paths ...string) error {
var op errors.Op = "plugins.ensureDirs"
for _, p := range paths {
err := os.MkdirAll(p, 0o755)
if err != nil {
return errors.E(op, fmt.Errorf("failed to ensure create directory %q: %w", p, err))
}
}
return nil
}
// IsSafePluginName checks if the plugin Name is safe to use.
func IsSafePluginName(name string) bool {
if !safePluginRegexp.MatchString(name) {
return false
}
for _, forbidden := range windowsForbidden {
if strings.EqualFold(forbidden, name) {
return false
}
}
View on GitHub (pinned to 724551b9ae)
Solutions
- Check the path in the message: if a file exists where a directory is expected, move/remove it.
- Fix ownership/permissions: mkdir -p the directory yourself and chown it to the running user (sudo chown -R $(whoami) <dir>).
- If read-only (container/snap), point the plugin dir at a writable location via configuration.
Example fix
# before $ plugin-cli install ... # EACCES on /usr/local/lib/plugins # after $ sudo mkdir -p /usr/local/lib/plugins && sudo chown -R $(whoami) /usr/local/lib/plugins $ plugin-cli install ...
Defensive patterns
Strategy: try-catch
Validate before calling
for _, dir := range []string{pluginDir, binDir} {
if fi, err := os.Stat(dir); err == nil && !fi.IsDir() {
return fmt.Errorf("%s exists and is not a directory", dir)
}
if err := os.MkdirAll(dir, 0o755); err != nil {
return fmt.Errorf("pre-create %s: %w", dir, err)
}
} Try / catch
if err := plugins.Prepare(...); err != nil {
if errors.Is(err, fs.ErrPermission) {
// prompt user to fix ownership or choose a user-writable dir
}
} Prevention
- Pre-create the plugin/bin directories with correct ownership during setup.
- Never run the installer against dirs owned by root unless the process runs as root.
- On read-only environments, configure a writable plugin directory.
When it happens
Trigger: Prepare → ensureDirs hitting: a parent directory in the path owned by another user (EACCES), an existing regular file where a directory is expected (ENOTDIR), a read-only filesystem, or an invalid path string.
Common situations: Installing a plugin into a bin/plugins dir under $HOME with wrong ownership after running the CLI with sudo; a config file sitting where a directory should be; disk full or read-only mounts in containers.
Related errors
- could not create staging dir %q: %w
- failed to remove old symlink: %w
- installation receipt could not be stored, uninstall may fail
- could not remove plugin directory %q: %w
- failed while moving files to the installation directory: %w
AI-assisted analysis of hasura/graphql-engine@724551b9ae (2026-08-28).
Data as JSON: /api/errors/f3942e0ca7b439d7.
Report an issue: GitHub.