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

  1. Verify dataDir exists and is writable by the process user (ls -ld <dataDir>; mkdir/chown as needed)
  2. If a file named 'run' exists in dataDir, remove or rename it so MkdirAll can create the directory
  3. Point dataDir at a writable location via configuration/flag (e.g. XDG data dir)
  4. 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

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


AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06). Data as JSON: /api/errors/58e1e47609d56bf7. Report an issue: GitHub.