chenhg5/cc-connect · error
create run dir: %w
Error message
create run dir: %w
What it means
NewAPIServer creates <dataDir>/run to host the API Unix domain socket; if os.MkdirAll fails the error is wrapped as "create run dir: %w". This is an mkdir/permission problem on the data directory, not a network issue.
Source
Thrown at core/api.go:69
Project string `json:"project"`
SessionKey string `json:"session_key"`
Message string `json:"message"`
WorkDir string `json:"work_dir,omitempty"`
CWD string `json:"cwd,omitempty"`
TTSText string `json:"tts_text,omitempty"`
Images []ImageAttachment `json:"images,omitempty"`
Files []FileAttachment `json:"files,omitempty"`
Audios []FileAttachment `json:"audios,omitempty"`
Videos []FileAttachment `json:"videos,omitempty"`
AtUsers []string `json:"at_users,omitempty"`
AtAll bool `json:"at_all,omitempty"`
}
// NewAPIServer creates an API server on a Unix socket.
func NewAPIServer(dataDir string) (*APIServer, error) {
sockDir := filepath.Join(dataDir, "run")
if err := os.MkdirAll(sockDir, 0o755); err != nil {
return nil, fmt.Errorf("create run dir: %w", err)
}
sockPath := filepath.Join(sockDir, "api.sock")
// Remove stale socket
os.Remove(sockPath)
listener, err := net.Listen("unix", sockPath)
if err != nil {
return nil, fmt.Errorf("listen unix socket: %w", err)
}
if err := os.Chmod(sockPath, 0o600); err != nil {
_ = listener.Close()
return nil, fmt.Errorf("chmod socket: %w", err)
}
s := &APIServer{
socketPath: sockPath,
listener: listener,View on GitHub (pinned to 4000b2338a)
Solutions
- Verify dataDir exists and is writable by the process user (ls -ld <dataDir>; mkdir/chown as needed)
- If a file named 'run' exists in dataDir, remove or rename it so MkdirAll can create the directory
- Point dataDir at a writable location via configuration/flag (e.g. XDG data dir)
- In containers, mount the data dir as a writable volume
Example fix
// before
srv, err := core.NewAPIServer("/etc/cc-connect") // root-owned, read-only
// after
srv, err := core.NewAPIServer("/home/user/.local/share/cc-connect") Defensive patterns
Strategy: validation
Validate before calling
if fi, err := os.Stat(dataDir); err != nil {
return fmt.Errorf("dataDir does not exist or is unreadable: %w", err)
} else if !fi.IsDir() {
return fmt.Errorf("dataDir is not a directory")
} else if err := syscall.Access(dataDir, os.O_WRONLY); err != nil {
return fmt.Errorf("dataDir not writable by current user")
} Try / catch
srv, err := core.NewAPIServer(dataDir)
if err != nil {
if strings.Contains(err.Error(), "create run dir") {
slog.Error("cannot create run dir; check dataDir ownership/permissions", "err", err)
}
return err
} Prevention
- Default dataDir to the user's XDG data directory, not /etc or /var
- Ensure nothing named 'run' exists as a plain file inside dataDir
- Mount writable volumes for dataDir in containers
- Check permissions after installing as a different user
When it happens
Trigger: Calling core.NewAPIServer(dataDir) with a dataDir whose parent does not exist and cannot be created (permission denied), or which is read-only, or where a non-directory file already exists at the run path.
Common situations: dataDir points to root-owned or read-only location while running as unprivileged user; a plain file named 'run' already exists in dataDir; running in a container with a read-only volume mounted at dataDir.
Understand the failure class
Background: mkdir permission denied (EACCES): failed to create directory errors explained — this error's family across 32 libraries.
Related errors
- chmod socket: %w
- read existing Agy hooks %s: %w
- kimi: read sessions dir: %w
- create systemd dir: %w
- write unit file: %w
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/58e1e47609d56bf7.
Report an issue: GitHub.