matryer/xbar · error
create directory %s for plugin
Error message
create directory %s for plugin
What it means
Returned by writePluginFiles when os.MkdirAll fails to create the parent directory of the destination plugin file during installation. It wraps the underlying OS error with the target directory path, so the cause is typically a filesystem permission problem or an invalid/occupied path. The library creates the directory with 0777 (before umask) before writing the plugin file into it.
Source
Thrown at pkg/plugins/install.go:117
}
return candidatePath, nil
}
// writePluginFiles iterates through the files defined for the plugin, and
// writes them to the plugin installation directory, and sets the entry point
// to be executable.
func (i Installer) writePluginFiles(dstPath string, plugin metadata.Plugin) error {
if len(plugin.Files) == 0 {
return errors.New("no plugin files")
}
if len(plugin.Files) > 1 {
return errors.Errorf("only one plugin file supported: found %d.", len(plugin.Files))
}
for _, f := range plugin.Files {
pluginFile := dstPath
dir := path.Dir(pluginFile)
if err := os.MkdirAll(dir, 0777); err != nil {
return errors.Wrapf(err, "create directory %s for plugin", dir)
}
writer, err := os.Create(pluginFile)
if err != nil {
return errors.Wrapf(err, "create plugin file %s", f.Path)
}
defer writer.Close()
reader := strings.NewReader(f.Content)
if _, err := io.Copy(writer, reader); err != nil {
return errors.Wrapf(err, "write plugin file %s", f.Path)
}
// If the Filename property of the current file matches the Filename
// property of the plugin, this is the entry point, so set it to be
// executable.
if f.Filename != plugin.Filename {
continue
}
if err := os.Chmod(pluginFile, 0755); err != nil {
return errors.Wrap(err, "set executable permission on plugin entry point")View on GitHub (pinned to d624239058)
Solutions
- Check and fix permissions on the parent directory (chown/chmod or run as a user with write access).
- Verify PluginDir/dstPath is correct and no file occupies a path component (ls the intermediate path).
- Ensure the filesystem is writable (not read-only mount) and path length is within limits.
- Pre-create the plugin directory manually with mkdir -p and correct ownership, then retry Install.
Example fix
// before (fails: ~/.upterm/plugins owned by root)
installer.Install(plugin)
// after
err := exec.Command("sudo", "chown", os.Getuid(), pluginDir).Run()
if err != nil { log.Fatal(err) }
err = installer.Install(plugin) Defensive patterns
Strategy: validation
Validate before calling
func canWriteDir(dir string) error {
for p := dir; ; p = filepath.Dir(p) {
if _, err := os.Stat(p); err == nil {
f, err := os.CreateTemp(p, ".write-test")
if err != nil { return err }
f.Close(); os.Remove(f.Name())
return nil
} else if !os.IsNotExist(err) {
return err
}
if p == "/" { return os.ErrPermission }
}
}
// call: if err := canWriteDir(filepath.Dir(dstPath)); err != nil { return err } Try / catch
err := installer.Install(plugin)
if err != nil {
if strings.Contains(err.Error(), "create directory") {
var pe *os.PathError
if errors.As(err, &pe) && os.IsPermission(pe) {
log.Fatalf("no permission to create %s: %v", pe.Path, pe.Err)
}
}
return err
} Prevention
- Ensure the process user owns or has write access to the plugin directory's parent.
- Never point PluginDir at read-only or system-managed paths.
- Pre-create the plugin directory at startup with correct permissions.
- Avoid paths where an intermediate component could be a regular file.
When it happens
Trigger: Calling Installer.Install (via writePluginFiles) when the parent directory of dstPath cannot be created: no write permission on an ancestor directory, a path component is an existing regular file, pluginDir points to read-only media, or the path is too long.
Common situations: Installing plugins into a system-wide directory as a non-root user; a stale regular file occupies part of the path; read-only container filesystem or Docker volume; PluginDir configured with a typo making an illegal path.
Understand the failure class
Background: mkdir permission denied (EACCES): failed to create directory errors explained — this error's family across 32 libraries.
Related errors
- create plugin file %s
- set executable permission on plugin entry point
- write plugin file %s
- write default variables
- ReadDir
AI-assisted analysis of matryer/xbar@d624239058 (2026-09-02).
Data as JSON: /api/errors/6114263b4ad07e60.
Report an issue: GitHub.