chenhg5/cc-connect · error

googlechat: build request: %w

Error message

googlechat: build request: %w

What it means

Wraps a failure from http.NewRequestWithContext when constructing the preview message POST in SendPreviewStart. Since the method is a constant, the only realistic cause is an invalid URL coming out of buildSendRequest.

Source

Thrown at platform/googlechat/streaming.go:39

// SendPreviewStart posts the initial streaming-preview message (threaded like a
// normal reply) and returns a handle for subsequent edits. Implements
// core.PreviewStarter; together with UpdateMessage it lights up the engine's
// real-time streaming preview for Google Chat.
func (p *Platform) SendPreviewStart(ctx context.Context, rctx any, content string) (any, error) {
	rc, ok := rctx.(replyContext)
	if !ok {
		return nil, fmt.Errorf("googlechat: invalid reply context type %T", rctx)
	}
	if rc.space == "" {
		return nil, fmt.Errorf("googlechat: missing space in reply context")
	}
	url, body, err := buildSendRequest(rc, content)
	if err != nil {
		return nil, err
	}
	req, err := http.NewRequestWithContext(ctx, http.MethodPost, url, bytes.NewReader(body))
	if err != nil {
		return nil, fmt.Errorf("googlechat: build request: %w", err)
	}
	req.Header.Set("Content-Type", "application/json")
	resp, err := p.doRequest(req)
	if err != nil {
		return nil, fmt.Errorf("googlechat: send preview: %w", err)
	}
	defer func() {
		if err := resp.Body.Close(); err != nil {
			slog.Warn("googlechat: close preview response body", "error", err)
		}
	}()
	var msg struct {
		Name string `json:"name"`
	}
	if err := json.NewDecoder(resp.Body).Decode(&msg); err != nil {
		return nil, fmt.Errorf("googlechat: parse create response: %w", err)
	}
	// drain any bytes json.Decoder left unread so the connection is reusable

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Log and validate the URL from buildSendRequest with url.Parse
  2. Confirm the Chat API base URL is the standard https://chat.googleapis.com/v1/...
  3. URL-escape space and thread identifiers before interpolation

Example fix

// before
url := baseURL + "/spaces/" + rc.space + "/messages"
// after
url := baseURL + "/spaces/" + url.PathEscape(rc.space) + "/messages"
Defensive patterns

Strategy: validation

Validate before calling

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

Try / catch

if _, err := p.SendPreviewStart(ctx, rc, content); err != nil {
    if strings.Contains(err.Error(), "build request") { slog.Error("googlechat preview URL malformed", "error", err) }
    return err
}

Prevention

When it happens

Trigger: buildSendRequest returns a URL that fails URL parsing — usually an empty or malformed configured API base URL, or unescaped characters in the space name interpolated into the URL.

Common situations: Bad base-URL override in config; spaces/thread keys with special characters; regressions after library upgrades.

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/75c2e0c6b8dd8ac8. Report an issue: GitHub.