chenhg5/cc-connect · error
create systemd dir: %w
Error message
create systemd dir: %w
What it means
Install() wraps the os.MkdirAll failure for the systemd unit directory (e.g. /etc/systemd/system or ~/.config/systemd/user) in this error via fmt.Errorf with %w. It means the directory holding the cc-connect .service unit could not be created, typically due to filesystem permissions or a read-only root. It aborts the whole install before any unit file is written.
Source
Thrown at daemon/systemd.go:55
if err := checkSystemdRunning(false); err != nil {
return nil, err
}
return &systemdManager{system: false}, nil
}
func (m *systemdManager) Platform() string {
if m.system {
return "systemd (system)"
}
return "systemd (user)"
}
func (m *systemdManager) Install(cfg Config) error {
unitPath := m.unitPath()
if err := os.MkdirAll(filepath.Dir(unitPath), 0755); err != nil {
return fmt.Errorf("create systemd dir: %w", err)
}
if err := os.MkdirAll(filepath.Dir(cfg.LogFile), 0755); err != nil {
return fmt.Errorf("create log dir: %w", err)
}
unit := m.buildUnit(cfg)
// 0600: unit file may contain captured secret values (config.toml ${ENV}
// placeholders and any EnvDiscoverer extension output). For system-level
// units (/etc/systemd/system/) the file is owned by root and remains
// readable by root only; for user-level units under
// ~/.config/systemd/user it remains owner-only. WriteFile only applies
// perm on create, so Chmod afterwards is required to harden reinstalls
// of pre-existing 0644 units from earlier cc-connect versions.
if err := os.WriteFile(unitPath, []byte(unit), 0600); err != nil {
return fmt.Errorf("write unit file: %w", err)
}
if err := os.Chmod(unitPath, 0600); err != nil {
return fmt.Errorf("chmod unit file: %w", err)View on GitHub (pinned to 4000b2338a)
Solutions
- Run the install command with root privileges (sudo) for a system-level unit.
- Check the target path: if a file exists where the directory should be, remove/rename it.
- Verify the filesystem is writable (not mounted ro): `mount | grep /etc`.
- Use a user-level manager (systemd --user) which writes under ~/.config and needs no root.
Example fix
// before
err := mgr.Install(cfg) // fails: create systemd dir: permission denied
// after
if os.Geteuid() != 0 && strings.HasPrefix(mgr.unitPath(), "/etc/") {
return fmt.Errorf("system install requires root; use --user")
}
err := mgr.Install(cfg) Defensive patterns
Strategy: try-catch
Validate before calling
unitDir := filepath.Dir(mgr.unitPath())
if fi, err := os.Stat(unitDir); err == nil && !fi.IsDir() {
return fmt.Errorf("%s exists and is not a directory", unitDir)
}
if err := os.MkdirAll(unitDir, 0755); err != nil {
return fmt.Errorf("cannot create unit dir: %w", err)
} Type guard
func canWriteDir(path string) bool {
fi, err := os.Stat(path)
return err == nil && fi.IsDir() && fi.Mode().Perm()&0200 != 0
} Try / catch
if err := mgr.Install(cfg); err != nil {
var pe *fs.PathError
if errors.As(err, &pe) && errors.Is(pe.Err, fs.ErrPermission) {
return fmt.Errorf("need root: rerun with sudo (%w)", err)
}
return err
} Prevention
- Check for root (os.Geteuid()==0) before system-level installs.
- Stat the target directory before install to catch file-instead-of-directory conflicts.
- Prefer user-level units under ~/.config when running unprivileged.
- Handle %w-wrapped errors with errors.As/errors.Is, never string matching.
When it happens
Trigger: Calling Install when the parent of unitPath cannot be created: insufficient privileges for /etc/systemd/system, a read-only filesystem, or a path component that is a regular file instead of a directory.
Common situations: Running `cc-connect install` as a non-root user for a system-level install; running inside a container with a read-only /etc; a stale file (not directory) sitting at ~/.config/systemd.
Understand the failure class
Background: mkdir permission denied (EACCES): failed to create directory errors explained — this error's family across 32 libraries.
Related errors
- write unit file: %w
- remove unit: %w
- read existing Agy hooks %s: %w
- kimi: read sessions dir: %w
- create run dir: %w
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/f97ec3a7427350b6.
Report an issue: GitHub.