chenhg5/cc-connect · error
remove unit: %w
Error message
remove unit: %w
What it means
Uninstall() wraps os.Remove failure for the unit file. Only unexpected errors (anything other than os.IsNotExist) are wrapped; disable and daemon-reload failures are merely logged. It means the unit file exists but could not be deleted.
Source
Thrown at daemon/systemd.go:96
m.sysArgs("enable", systemdServiceName),
m.sysArgs("restart", systemdServiceName),
} {
if out, err := runSystemctl(cmdArgs...); err != nil {
return fmt.Errorf("systemctl %s: %s (%w)", strings.Join(cmdArgs, " "), out, err)
}
}
return nil
}
func (m *systemdManager) Uninstall() error {
if _, err := runSystemctl(m.sysArgs("disable", "--now", systemdServiceName)...); err != nil {
slog.Warn("systemd: disable failed", "error", err)
}
unitPath := m.unitPath()
if err := os.Remove(unitPath); err != nil && !os.IsNotExist(err) {
return fmt.Errorf("remove unit: %w", err)
}
if _, err := runSystemctl(m.sysArgs("daemon-reload")...); err != nil {
slog.Warn("systemd: daemon-reload failed", "error", err)
}
return nil
}
func (m *systemdManager) Start() error {
out, err := runSystemctl(m.sysArgs("start", systemdServiceName)...)
if err != nil {
return fmt.Errorf("start: %s (%w)", out, err)
}
return nil
}
func (m *systemdManager) Stop() error {
out, err := runSystemctl(m.sysArgs("stop", systemdServiceName)...)View on GitHub (pinned to 4000b2338a)
Solutions
- Run the uninstall with sudo for system-level units.
- Check ownership of the unit file: `ls -l <unitPath>` and chown if needed.
- Delete manually and reload: `sudo rm <unitPath> && sudo systemctl daemon-reload`.
- Ensure the filesystem is writable.
Example fix
// before
cmd.Exec("cc-connect uninstall") // remove unit: permission denied
// after
cmd.Exec("sudo cc-connect uninstall") Defensive patterns
Strategy: try-catch
Validate before calling
unitPath := mgr.unitPath()
if _, err := os.Stat(unitPath); os.IsNotExist(err) {
return nil // nothing to uninstall
}
if err := syscall.Access(filepath.Dir(unitPath), 0o200); err != nil {
return fmt.Errorf("no write permission on %s; rerun with sudo", filepath.Dir(unitPath))
} Type guard
func unitRemovable(unitPath string) bool {
return err := os.Remove(unitPath); err == nil || os.IsNotExist(err)
} Try / catch
if err := mgr.Uninstall(); err != nil {
var pe *fs.PathError
if errors.As(err, &pe) && errors.Is(pe.Err, fs.ErrPermission) {
return fmt.Errorf("use sudo: %w", err)
}
return err
} Prevention
- Check unit ownership before uninstalling at a different privilege level.
- Treat IsNotExist as success (idempotent uninstall).
- Verify the unit directory is writable before removal.
- After removal, confirm with systemctl cat cc-connect.
When it happens
Trigger: Calling Uninstall when unitPath exists but the process lacks write permission on the unit directory, the unit file is owned by another user, or the filesystem is read-only.
Common situations: Uninstalling a root-installed unit as a normal user; unit directory permissions tightened by an admin; container/WSL with read-only /etc.
Understand the failure class
Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.
Related errors
- create systemd dir: %w
- write unit file: %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/f2006fa0754335fa.
Report an issue: GitHub.