chenhg5/cc-connect · error

googlechat: attachment message: build request: %w

Error message

googlechat: attachment message: build request: %w

What it means

This wraps an http.NewRequestWithContext failure while building the JSON POST that creates a Chat message referencing an uploaded attachment. NewRequest only errors on invalid URL or unsupported methods, so this almost always means the URL produced by buildAttachmentRequest is malformed.

Source

Thrown at platform/googlechat/googlechat.go:542

}

// postAttachment uploads data then creates a Chat message carrying the
// attachmentDataRef. Shared by SendImage and SendFile.
func (p *Platform) postAttachment(ctx context.Context, rc replyContext, filename, mimeType string, data []byte) error {
	if rc.space == "" {
		return fmt.Errorf("googlechat: missing space in reply context")
	}
	resourceName, err := p.uploadAttachment(ctx, rc.space, filename, mimeType, data)
	if err != nil {
		return err
	}
	url, body, err := buildAttachmentRequest(rc, resourceName)
	if err != nil {
		return err
	}
	req, err := http.NewRequestWithContext(ctx, http.MethodPost, url, bytes.NewReader(body))
	if err != nil {
		return fmt.Errorf("googlechat: attachment message: build request: %w", err)
	}
	req.Header.Set("Content-Type", "application/json")
	resp, err := p.doRequest(req)
	if err != nil {
		return err
	}
	if _, err := io.Copy(io.Discard, resp.Body); err != nil {
		_ = resp.Body.Close()
		return fmt.Errorf("googlechat: drain attachment create response body: %w", err)
	}
	if err := resp.Body.Close(); err != nil {
		return fmt.Errorf("googlechat: close attachment create response body: %w", err)
	}
	return nil
}

// SendImage uploads an image and posts it as a Chat message attachment.
// Implements core.ImageSender.

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Print/log the URL produced by buildAttachmentRequest and validate it parses with url.Parse
  2. Verify the API base URL configuration points at https://chat.googleapis.com/...
  3. Ensure the attachmentDataRef resource name is URL-escaped before being placed in the request path

Example fix

// before
url := apiBase + rc.space + "/attachments" // raw space name
// after
url := apiBase + url.PathEscape(rc.space) + "/attachments"
Defensive patterns

Strategy: try-catch

Validate before calling

if _, err := url.Parse(requestURL); err != nil || !strings.HasPrefix(requestURL, "https://") { return fmt.Errorf("invalid attachment URL: %w", err) }

Try / catch

if err := p.SendFile(ctx, rc, file); err != nil {
    if strings.Contains(err.Error(), "build request") {
        slog.Error("googlechat attachment URL invalid", "error", err)
    }
    return err
}

Prevention

When it happens

Trigger: buildAttachmentRequest returns a URL that fails net/http URL parsing — e.g. missing/empty base API URL in configuration producing a non-absolute URL, or mis-escaped characters in the space/resource name interpolated into the path.

Common situations: Deployments overriding the Chat API base URL with a bad value; space names containing characters that break URL construction; regression in buildAttachmentRequest after a version upgrade.

Understand the failure class

Background: "Invalid URL" / "URL cannot be empty": fix the malformed or missing URL behind request-construction failures — this error's family across 50 libraries.

Related errors


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