chenhg5/cc-connect · error

matrix: send encrypted: %w

Error message

matrix: send encrypted: %w

What it means

This error wraps a failure from client.SendMessageEvent when delivering an already-encrypted event (type m.room.encrypted) to the homeserver. The content encrypted fine, but the HTTP transaction to send it failed, so the message was not delivered.

Source

Thrown at platform/matrix/e2ee.go:243

// tryEncryptAndSend attempts to encrypt and send an event if E2EE is available.
// Returns (true, nil) if handled, (true, err) if handled with error, (false, nil) if not handled.
func (p *Platform) tryEncryptAndSend(ctx context.Context, client *mautrix.Client, roomID id.RoomID, evtType event.Type, content any) (bool, error) {
	ch := p.getE2EECryptoHelper()
	if ch == nil {
		return false, nil
	}
	if !p.isRoomEncrypted(ctx, roomID) {
		return false, nil
	}

	encContent, err := ch.Encrypt(ctx, roomID, evtType, content)
	if err != nil {
		return true, fmt.Errorf("matrix: encrypt: %w", err)
	}
	_, err = client.SendMessageEvent(ctx, roomID, event.EventEncrypted, encContent)
	if err != nil {
		return true, fmt.Errorf("matrix: send encrypted: %w", err)
	}
	return true, nil
}

func (p *Platform) isRoomEncrypted(ctx context.Context, roomID id.RoomID) bool {
	client := p.getClient()
	if client == nil || client.StateStore == nil {
		return false
	}
	ss, ok := client.StateStore.(crypto.StateStore)
	if !ok {
		return false
	}
	enc, err := ss.IsEncrypted(ctx, roomID)
	if err != nil {
		return false
	}
	return enc

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Check the wrapped cause for an HTTP status: 403 means join the room first (verify auto-join completed), 429 means back off and retry per Retry-After.
  2. Verify connectivity to the homeserver (curl /_matrix/client/versions) and retry the send.
  3. Ensure the room ID is correct and the bot account is a joined member of that room.
  4. Implement/raise retry with backoff for transient 5xx/network errors before surfacing to the user.
  5. Check homeserver logs for the corresponding request rejection if client-side details are insufficient.

Example fix

// before
_, err = client.SendMessageEvent(ctx, roomID, event.EventEncrypted, encContent)
if err != nil {
    return true, fmt.Errorf("matrix: send encrypted: %w", err)
}
// after
_, err = client.SendMessageEvent(ctx, roomID, event.EventEncrypted, encContent)
if err != nil {
    if errors.Is(err, mautrix.MForbidden) {
        slog.Warn("matrix: not allowed to send, bot may not be joined", "room", roomID)
    }
    return true, fmt.Errorf("matrix: send encrypted: %w", err)
}
Defensive patterns

Strategy: retry

Validate before calling

// Go: verify bot membership before attempting an encrypted send
members, err := client.JoinedMembers(ctx, roomID)
if err != nil || !containsUser(members, client.UserID) {
    return fmt.Errorf("bot not joined to %s; skipping encrypted send", roomID)
}

Try / catch

_, err = client.SendMessageEvent(ctx, roomID, event.EventEncrypted, encContent)
var httpErr mautrix.HTTPError
if errors.As(err, &httpErr) {
    switch httpErr.Response.StatusCode {
    case 403: // join room / fix permissions then retry
    case 429: // honor Retry-After then retry
    default:  // surface with backoff
    }
}

Prevention

When it happens

Trigger: sendRoomEvent → tryEncryptAndSend: encryption succeeded, then client.SendMessageEvent(ctx, roomID, event.EventEncrypted, encContent) returns err — network failure, homeserver 4xx/5xx (e.g. 403 forbidden because the bot is not joined to the room, 429 rate limit), or request timeout.

Common situations: Bot invite not yet accepted so the homeserver rejects the send (M_FORBIDDEN); homeserver outage or restart mid-send; network partition between bridge and homeserver; hitting sync/send rate limits in a busy room.

Understand the failure class

Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.

Related errors


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