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
- Inspect the wrapped inner error: if it's url.Parse-related, sanitize the space/thread values (reject control/whitespace characters when building replyContext)
- If it's a context-canceled error, check upstream cancellation — recreate the context or skip sends on shutdown
- 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
- Sanitize space/thread values parsed from inbound events before storing them in replyContext
- Don't reuse contexts across long-lived operations; create one per send
- Validate session keys on save so invalid characters never reach URL construction
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
- googlechat: attachment message: build request: %w
- googlechat: build request: %w
- googlechat: build update request: %w
- reasonix: create request: %w
- create request: %w
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/ce3d2c27be32829e.
Report an issue: GitHub.