chenhg5/cc-connect · error
create data dir: %w
Error message
create data dir: %w
What it means
After computing the crypto directory (~/.cc-connect), initCrypto calls os.MkdirAll with mode 0o700 and wraps failure as "create data dir: %w". This is a filesystem permission or I/O error preventing creation of the E2EE state database directory. The library needs this directory to persist Matrix crypto (megolm) sessions.
Source
Thrown at platform/matrix/e2ee.go:179
slog.Warn("matrix: verification helper not available", "error", vErr)
} else {
slog.Info("matrix: SAS verification enabled", "mode", "auto-verify")
}
}
}
func (p *Platform) initCrypto(ctx context.Context, client *mautrix.Client) (*cryptohelper.CryptoHelper, error) {
if client.DeviceID == "" {
return nil, fmt.Errorf("device ID not available from whoami")
}
homeDir, err := os.UserHomeDir()
if err != nil {
return nil, fmt.Errorf("get home dir: %w", err)
}
cryptoDir := filepath.Join(homeDir, ".cc-connect")
if err := os.MkdirAll(cryptoDir, 0o700); err != nil {
return nil, fmt.Errorf("create data dir: %w", err)
}
dbPath := filepath.Join(cryptoDir, fmt.Sprintf("matrix-crypto-%s.db", client.DeviceID))
// Derive a stable pickle key from the access token
h := sha256.Sum256([]byte(p.accessToken))
pickleKey := make([]byte, 32)
copy(pickleKey, h[:])
return p.tryInitCrypto(ctx, client, pickleKey, dbPath, false)
}
func (p *Platform) tryInitCrypto(ctx context.Context, client *mautrix.Client, pickleKey []byte, dbPath string, isRetry bool) (*cryptohelper.CryptoHelper, error) {
ch, err := cryptohelper.NewCryptoHelper(client, pickleKey, dbPath)
if err != nil {
return nil, fmt.Errorf("create crypto helper: %w", err)
}
ch.DBAccountID = client.UserID.String()
View on GitHub (pinned to 4000b2338a)
Solutions
- Ensure the process's home directory exists and is writable by the running user (chown/chmod)
- Check ~/.cc-connect isn't a regular file; remove/rename it if so
- Mount a writable volume at the data path in containers (e.g. -v ccdata:/home/user/.cc-connect)
- Inspect the wrapped error (permissions vs read-only fs) with ls -ld ~/.cc-connect and mount/dmesg for denials
Example fix
# before ls -ld ~/.cc-connect # after mkdir -p ~/.cc-connect && chown $(whoami) ~/.cc-connect && chmod 700 ~/.cc-connect
Defensive patterns
Strategy: try-catch
Validate before calling
dir := filepath.Join(home, ".cc-connect")
if info, err := os.Stat(dir); err == nil && !info.IsDir() {
return fmt.Errorf("%s exists and is not a directory", dir)
}
if err := unix.Access(dir, unix.W_OK); err != nil {
return fmt.Errorf("%s is not writable: %v", dir, err)
} Type guard
null
Try / catch
if err != nil {
if strings.Contains(err.Error(), "create data dir") {
slog.Error("cannot create crypto store dir", "dir", filepath.Join(home, ".cc-connect"), "err", err)
// fall back to a writable temp dir or disable E2EE
return nil
}
return fmt.Errorf("init e2ee: %w", err)
} Prevention
- Provision a writable volume at the crypto data path in containers
- Keep the running user's home owned by that user with 700 permissions
- Ensure ~/.cc-connect is never replaced by a regular file
- Check for read-only mounts or SELinux/AppArmor denials when deploying
When it happens
Trigger: os.MkdirAll(homeDir/.cc-connect, 0o700) fails because a parent path exists as a file, the process lacks write permission on $HOME, the filesystem is read-only, or disk is full.
Common situations: Running in a container with read-only root filesystem and no writable volume at $HOME; $HOME owned by another user; ~/.cc-connect path shadowed by a regular file; SELinux/AppArmor denials.
Understand the failure class
Background: mkdir permission denied (EACCES): failed to create directory errors explained — this error's family across 32 libraries.
Related errors
- codex: mkdir codex home: %w
- cannot create config directory: %w
- cannot create config directory: %w
- create data dir: %w
- get home dir: %w
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/9dbdf242a2719f04.
Report an issue: GitHub.