chenhg5/cc-connect · error
cloud_web: ws_url or base_url is required for websocket tran
Error message
cloud_web: ws_url or base_url is required for websocket transport
What it means
The cloud_web constructor requires a usable endpoint when transport is "websocket". resolveWSURL(baseURL, wsURL) derives the WebSocket URL from ws_url or base_url; if both are empty/blank, no connection target exists and New returns this error.
Source
Thrown at platform/cloud-web/cloudweb.go:103
listen, _ := opts["listen"].(string)
webhookPath, _ := opts["webhook_path"].(string)
registerURL, _ := opts["register_url"].(string)
publicURL, _ := opts["public_url"].(string)
eventsPath, _ := opts["events_path"].(string)
sendPath, _ := opts["send_path"].(string)
longPollMS := pickInt(opts["long_poll_timeout_ms"])
allowFrom, _ := opts["allow_from"].(string)
core.CheckAllowFrom(name, allowFrom)
shareInChannel, _ := opts["share_session_in_channel"].(bool)
groupReplyAll, _ := opts["group_reply_all"].(bool)
var tp transport
switch transportKind {
case "websocket":
resolved := resolveWSURL(baseURL, wsURL)
if strings.TrimSpace(resolved) == "" {
return nil, fmt.Errorf("cloud_web: ws_url or base_url is required for websocket transport")
}
tp = newWSTransport(resolved, token, name, project)
case "long_poll":
if strings.TrimSpace(baseURL) == "" {
return nil, fmt.Errorf("cloud_web: base_url is required for long_poll transport")
}
tp = newPollTransport(baseURL, token, name, project, eventsPath, sendPath, longPollMS)
case "gateway":
if strings.TrimSpace(baseURL) == "" && strings.TrimSpace(registerURL) != "" {
baseURL = deriveBaseURL(registerURL)
}
if strings.TrimSpace(baseURL) == "" && strings.TrimSpace(registerURL) == "" {
return nil, fmt.Errorf("cloud_web: base_url or register_url is required for gateway transport")
}
if strings.TrimSpace(registerURL) != "" && strings.TrimSpace(publicURL) == "" {
return nil, fmt.Errorf("cloud_web: public_url is required when register_url is set for gateway transport")
}
tp = newGatewayTransport(baseURL, token, name, project, listen, webhookPath, registerURL, publicURL, sendPath)View on GitHub (pinned to 4000b2338a)
Solutions
- Add `base_url = "https://<your-cloud-web-host>"` to the cloud_web platform options.
- Or set `ws_url = "wss://<host>/ws"` directly for an explicit WebSocket endpoint.
- Verify both values are quoted non-empty strings (check unexpanded env placeholders).
- If you only have an HTTP endpoint for polling, set `transport = "long_poll"` with base_url instead.
Example fix
// before
opts := map[string]any{"token": tok} // websocket default, no endpoint
p, err := cloudweb.New(opts)
// after
opts := map[string]any{"token": tok, "base_url": "https://cloud.example.com"}
p, err := cloudweb.New(opts) Defensive patterns
Strategy: validation
Validate before calling
func hasWSEndpoint(opts map[string]any) bool {
ws, _ := opts["ws_url"].(string)
base, _ := opts["base_url"].(string)
return strings.TrimSpace(ws) != "" || strings.TrimSpace(base) != ""
} Type guard
func hasNonEmptyString(opts map[string]any, key string) bool {
s, ok := opts[key].(string)
return ok && strings.TrimSpace(s) != ""
}
// use: hasNonEmptyString(opts, "ws_url") || hasNonEmptyString(opts, "base_url") Try / catch
p, err := cloudweb.New(opts)
if err != nil {
if strings.Contains(err.Error(), "ws_url or base_url is required") {
slog.Error("cloud_web: add base_url (https://host) or ws_url (wss://host/ws) for websocket transport")
return
}
return err
} Prevention
- Always set base_url (or ws_url) alongside token for cloud_web.
- Quote URL values as strings; avoid unexpanded env placeholders.
- When switching from long_poll to websocket, carry base_url over.
- Add a startup config check that both token and an endpoint exist for websocket transport.
When it happens
Trigger: Calling cloudweb.New with transport unset or "websocket" while both opts["ws_url"] and opts["base_url"] are missing, non-string, or whitespace-only.
Common situations: Config block containing token but no server URL; ws_url/base_url provided as non-string types (number, bool); empty strings from unexpanded env placeholders; switching transports to websocket without carrying over base_url from a long_poll config.
Understand the failure class
Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.
Related errors
- cloud_web: transport must be websocket, long_poll, or gatewa
- cloud_web: base_url is required for long_poll transport
- cloud_web: base_url or register_url is required for gateway
- parse ws url: %w
- tmux: 'session' option is required (name of the tmux session
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/1a9e7aebd84b86d0.
Report an issue: GitHub.