chenhg5/cc-connect · error

parse content URI: %w

Error message

parse content URI: %w

What it means

downloadMediaContent wraps a parse failure of the Matrix content URI (mxc://...) with "parse content URI: %w". Matrix media must be referenced by a valid mxc URI that can be decomposed into server name and media ID before the client can call Download. An unparseable URI means the message event carried malformed or missing media metadata.

Source

Thrown at platform/matrix/matrix.go:681

		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
	}
	mime := ""
	if content.Info != nil {
		mime = content.Info.MimeType
	}

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Log the offending content URL string to see what was actually received
  2. Verify the event is a plain (non-encrypted) media event; for encrypted rooms read the URL from the decrypted content
  3. Validate the mxc URI format (mxc://<server>/<mediaId>) before passing it, and skip non-media events
  4. If a bridge is producing bad URIs, fix or update the bridge

Example fix

// before
resp, err := p.downloadMediaContent(ctx, contentURL)

// after
if !strings.HasPrefix(string(contentURL), "mxc://") {
    return nil, fmt.Errorf("matrix: not an mxc content URI: %q", contentURL)
}
resp, err := p.downloadMediaContent(ctx, contentURL)
Defensive patterns

Strategy: validation

Validate before calling

u := string(contentURL)
if !strings.HasPrefix(u, "mxc://") || len(strings.TrimPrefix(u, "mxc://")) == 0 {
    // skip: not a valid Matrix media URI
}

Type guard

func isMXC(u id.ContentURIString) bool {
    _, err := u.Parse()
    return err == nil
}

Try / catch

parsed, err := contentURL.Parse()
if err != nil {
    slog.Warn("matrix: skipping media with invalid URI", "url", string(contentURL), "err", err)
    return
}

Prevention

When it happens

Trigger: An image/file/audio message event contains a msgtype with a content URL that is empty, not an mxc:// URI, or otherwise malformed, so contentURL.Parse() inside downloadMediaContent returns an error.

Common situations: Receiving media from a bridge or non-standard client that sets a wrong URL field; an encrypted event where the actual URL is in a nested encrypted payload and the outer URL is blank; homeserver/bridge bugs emitting invalid mxc URIs.

Understand the failure class

Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.

Related errors


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