chenhg5/cc-connect · error
matrix: client not available
Error message
matrix: client not available
What it means
initVerification aborts E2EE device-verification setup with "matrix: client not available" when getClient() returns nil. Initializing the verification helper requires an authenticated Matrix client to register event handlers and access the crypto machine. Without a live client, verification cannot be set up.
Source
Thrown at platform/matrix/verification.go:202
// ConfirmSAS must run in a separate goroutine because onVerificationKey
// holds activeTransactionsLock when calling showSAS, and ConfirmSAS
// also acquires the same non-reentrant mutex.
go func() {
helper := vc.platform.getVerificationHelper()
if helper == nil {
return
}
if err := helper.ConfirmSAS(context.Background(), txnID); err != nil {
slog.Error("matrix: confirm SAS failed", "txn_id", txnID, "error", err)
}
}()
}
func (p *Platform) initVerification(ctx context.Context, ch *cryptohelper.CryptoHelper) error {
client := p.getClient()
if client == nil {
return fmt.Errorf("matrix: client not available")
}
// Wrap the client's actual HTTP transport. We must use client.Client directly
// (not p.httpClient) because cryptohelper.Init() may have replaced client.Client
// with a new http.Client instance.
if client.Client == nil {
return fmt.Errorf("matrix: client http.Client is nil")
}
base := client.Client.Transport
if base == nil {
base = http.DefaultTransport
}
client.Client.Transport = &encryptingTransport{base: base, p: p}
slog.Info("matrix: transport wrapped for verification encryption")
callbacks := &verificationCallbacks{platform: p}
helper := verificationhelper.NewVerificationHelper(client, ch.Machine(), nil, callbacks, false, false, true)
View on GitHub (pinned to 4000b2338a)
Solutions
- Make sure Start() successfully created the client before initE2EE runs — check earlier login errors
- Verify Matrix credentials/homeserver reachability so the client is actually established
- Order the startup sequence so E2EE/verification init happens after client creation
- If triggered by a reconnect race, guard initVerification with a connectivity check or retry after reconnect
Defensive patterns
Strategy: type-guard
Validate before calling
if p.getClient() == nil {
// postpone E2EE init until the client exists
} Type guard
func e2eeReady(p *Platform) bool { return p.getClient() != nil } Try / catch
if err := p.initVerification(ctx, ch); err != nil {
if strings.Contains(err.Error(), "client not available") {
// retry after (re)connect
return nil
}
return err
} Prevention
- Initialize E2EE strictly after successful client login
- Assert client != nil in startup sequencing tests
- Re-run verification init on every reconnect
When it happens
Trigger: initE2EE calls initVerification before the client is assigned (startup ordering issue), or after clearClient() nulled it (connection lost), so getClient() == nil at the start of initVerification.
Common situations: E2EE enabled in config but the initial login/sync failed, leaving the client nil; a race between connection teardown and E2EE initialization during a reconnect cycle.
Understand the failure class
Background: ECONNREFUSED and "connection refused" / "could not connect to server" errors: what they mean and how to fix them — this error's family across 44 libraries.
Related errors
- matrix: init verification: %w
- device ID not available from whoami
- get home dir: %w
- create data dir: %w
- create crypto helper: %w
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/a422fcd8a32dbda9.
Report an issue: GitHub.