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

  1. Ensure the process's home directory exists and is writable by the running user (chown/chmod)
  2. Check ~/.cc-connect isn't a regular file; remove/rename it if so
  3. Mount a writable volume at the data path in containers (e.g. -v ccdata:/home/user/.cc-connect)
  4. 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

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


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