chenhg5/cc-connect · error

not connected

Error message

not connected

What it means

downloadMediaContent returns "not connected" when the platform's Matrix client is nil, meaning the platform has not finished connecting or the connection was cleared. Media downloads (images, files, audio) require an authenticated client to fetch content from the Matrix homeserver, so they refuse to run without one. This is a state guard, not a network failure.

Source

Thrown at platform/matrix/matrix.go:677

func (p *Platform) isDirectedAtBot(content *event.MessageEventContent, selfID id.UserID) bool {
	// Check formatted body for matrix.to link
	if content.FormattedBody != "" {
		mention := fmt.Sprintf("https://matrix.to/#/%s", selfID)
		if strings.Contains(content.FormattedBody, mention) {
			return true
		}
	}
	// Check plain body for @user:server mention
	if strings.Contains(content.Body, selfID.String()) {
		return true
	}
	return false
}

func (p *Platform) downloadMediaContent(ctx context.Context, contentURL id.ContentURIString) ([]byte, error) {
	client := p.getClient()
	if client == nil {
		return nil, fmt.Errorf("not connected")
	}
	parsed, err := contentURL.Parse()
	if err != nil {
		return nil, fmt.Errorf("parse content URI: %w", err)
	}
	resp, err := client.Download(ctx, parsed)
	if err != nil {
		return nil, err
	}
	defer func() { _ = resp.Body.Close() }()
	return io.ReadAll(resp.Body)
}

func (p *Platform) downloadMedia(ctx context.Context, content *event.MessageEventContent) (*core.ImageAttachment, error) {
	data, err := p.downloadMediaContent(ctx, content.URL)
	if err != nil {
		return nil, err
	}

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Wait for the platform to finish connecting (ensure Start() succeeded) before sending/receiving media
  2. If this happens during operation, check why the connection dropped — look for preceding "matrix: connection lost" logs and fix network/credentials
  3. Guard download attempts: check client connectivity and skip or queue media when the client is unavailable
  4. If it occurs during shutdown, ignore it or add a connectivity check before calling downloadMediaContent

Example fix

// before
content, err := p.downloadMediaContent(ctx, ev.Content.URL)

// after
if p.getClient() == nil {
    return fmt.Errorf("matrix: cannot download media, not connected")
}
content, err := p.downloadMediaContent(ctx, ev.Content.URL)
Defensive patterns

Strategy: try-catch

Validate before calling

if p.getClient() == nil {
    // defer or skip media download
}

Type guard

func mediaReady(p *Platform) bool { return p.getClient() != nil }

Try / catch

content, err := p.downloadMediaContent(ctx, url)
if err != nil {
    if err.Error() == "not connected" {
        // queue for retry after reconnect
        return
    }
    return err
}

Prevention

When it happens

Trigger: Calling downloadMedia / downloadFileMedia / downloadAudioMedia (via downloadMediaContent) when p.getClient() returns nil — i.e., before Start() completes the client setup or after clearClient() nulled p.client during shutdown/reconnect.

Common situations: A media message arrives while the platform is reconnecting after a lost sync connection; messages queued during startup race with client initialization; Stop() was called (p.stopping) and clearClient() ran but in-flight event handling still tries to download an attachment.

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


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