chenhg5/cc-connect · error

googlechat: build request: %w

Error message

googlechat: build request: %w

What it means

post wraps http.NewRequestWithContext failures with this error. Since the URL is built from the validated reply context and the body is plain JSON bytes, this almost always means the URL failed http.NewRequest's parsing (control characters or invalid characters in the space/thread resource names) or the context was already canceled.

Source

Thrown at platform/googlechat/googlechat.go:427

	}
	return resp, nil
}

func (p *Platform) post(ctx context.Context, rctx any, content string) error {
	rc, ok := rctx.(replyContext)
	if !ok {
		return fmt.Errorf("googlechat: invalid reply context type %T", rctx)
	}
	if rc.space == "" {
		return fmt.Errorf("googlechat: missing space in reply context")
	}
	url, body, err := buildSendRequest(rc, content)
	if err != nil {
		return err
	}
	req, err := http.NewRequestWithContext(ctx, http.MethodPost, url, bytes.NewReader(body))
	if err != nil {
		return fmt.Errorf("googlechat: 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 response body: %w", err)
	}
	if err := resp.Body.Close(); err != nil {
		return fmt.Errorf("googlechat: close response body: %w", err)
	}
	return nil
}

func (p *Platform) Reply(ctx context.Context, rctx any, content string) error {
	return p.post(ctx, rctx, content)

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Inspect the wrapped inner error: if it's url.Parse-related, sanitize the space/thread values (reject control/whitespace characters when building replyContext)
  2. If it's a context-canceled error, check upstream cancellation — recreate the context or skip sends on shutdown
  3. Recreate the session if its stored space/thread fields were corrupted by bad input

Example fix

// before
thread := strings.TrimSpace(rawThread) // may still contain control chars
// after
if !validResourceName(thread) { return fmt.Errorf("googlechat: bad thread %q", thread) }
Defensive patterns

Strategy: validation

Validate before calling

func validResourceName(s string) bool {
    for _, r := range s { if r < 0x21 || r == 0x7f { return false } }
    return strings.HasPrefix(s, "spaces/")
}

Try / catch

if err := p.post(ctx, rc, content); err != nil {
    if errors.Is(err, context.Canceled) {
        slog.Info("send aborted: context canceled (shutdown?)")
        return err
    }
    return fmt.Errorf("send failed: %w", err)
}

Prevention

When it happens

Trigger: replyContext containing a space or thread value with invalid URL characters (newlines, spaces, control bytes) that make the composed URL unparseable, or a canceled/expired context passed to Reply/Send.

Common situations: Malicious or corrupted inbound event data used to build the space/thread fields; session keys containing whitespace; long-running operations whose context was canceled before the send.

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