chenhg5/cc-connect · error
cannot create config directory: %w
Error message
cannot create config directory: %w
What it means
AcquireInstanceLock creates the config directory (os.MkdirAll) before opening its lock file. If the directory cannot be created, the function fails with "cannot create config directory: %w". This is an OS-level failure (permissions, read-only filesystem, path is a file) surfaced before locking occurs.
Source
Thrown at cmd/cc-connect/instance_lock.go:37
// AcquireInstanceLock attempts to acquire an exclusive lock for the given config path.
// If another instance is already running with the same config, it returns an error
// containing the PID of the existing instance.
//
// The lock file is placed in the same directory as the config file, with a name
// derived from the config path hash. This allows different configs to run simultaneously.
func AcquireInstanceLock(configPath string) (*InstanceLock, error) {
// Create lock file path based on config path
configDir := filepath.Dir(configPath)
configBase := filepath.Base(configPath)
// Use a predictable name based on config filename
lockName := fmt.Sprintf(".%s.lock", configBase)
lockPath := filepath.Join(configDir, lockName)
// Ensure directory exists
if err := os.MkdirAll(configDir, 0755); err != nil {
return nil, fmt.Errorf("cannot create config directory: %w", err)
}
// Open/create the lock file
f, err := os.OpenFile(lockPath, os.O_CREATE|os.O_RDWR, 0644)
if err != nil {
return nil, fmt.Errorf("cannot open lock file: %w", err)
}
// Try to acquire exclusive lock (non-blocking)
err = syscall.Flock(int(f.Fd()), syscall.LOCK_EX|syscall.LOCK_NB)
if err != nil {
// Lock is held by another process
f.Close()
// Try to read PID from lock file for better error message
pid := readPIDFromLockFile(lockPath)
if pid > 0 {
return nil, fmt.Errorf("another cc-connect instance is already running (PID %d) with config %s", pid, configPath)View on GitHub (pinned to 4000b2338a)
Solutions
- Check permissions on the config directory's parent and create it manually: mkdir -p $(dirname <configPath>).
- Verify no regular file exists at the config directory path; remove or rename it.
- Check disk space (df -h) and mount status (mount | grep ro) for the filesystem holding the config.
- Pass a --config path in a writable location (e.g. ~/.config/cc-connect/config.toml).
Example fix
// before f, err := lock(configPath) // fails when ~/.config/cc-connect is unwritable // after // pre-create with correct ownership, then run // mkdir -p ~/.config/cc-connect && chown $USER ~/.config/cc-connect
Defensive patterns
Strategy: validation
Validate before calling
dir := filepath.Dir(configPath)
if fi, err := os.Stat(dir); err == nil && !fi.IsDir() {
return fmt.Errorf("%s is a file, not a directory", dir)
}
if err := os.MkdirAll(dir, 0755); err != nil {
return fmt.Errorf("config dir not creatable: %w", err)
} Try / catch
lock, err := AcquireInstanceLock(configPath)
if err != nil && strings.Contains(err.Error(), "cannot create config directory") {
slog.Error("check permissions/ownership of config dir", "dir", filepath.Dir(configPath), "err", err)
os.Exit(1)
} Prevention
- Run cc-connect as the user who owns the config directory.
- Pre-create the config directory with correct permissions during install.
- Keep config paths out of root-owned/system directories.
When it happens
Trigger: Calling AcquireInstanceLock(configPath) where filepath.Dir(configPath) does not exist and cannot be created: parent dir not writable, a non-directory file occupies the path, or the filesystem is read-only/full.
Common situations: Running cc-connect with a config path in a directory the user cannot write to (e.g. /etc or another user's home), a stale file named like the config dir, disk full, or read-only mount after system recovery.
Understand the failure class
Background: mkdir permission denied (EACCES): failed to create directory errors explained — this error's family across 32 libraries.
Related errors
- cannot create config directory: %w
- codex: mkdir codex home: %w
- cannot open lock file: %w
- cannot read sessions directory %s: %w
- read sessions dir: %w
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/de6c73d73abeb0a6.
Report an issue: GitHub.