chenhg5/cc-connect · critical
cloud_web: gateway listen: %w
Error message
cloud_web: gateway listen: %w
What it means
The cloud-web platform's gateway transport failed to bind its inbound webhook HTTP listener when Platform.Start() was called. The transport opens a TCP listener (default :8099) so the cloud-web bridge can POST events to it; if net.Listen fails the whole Start fails and the platform cannot start. The wrapped OS error tells you exactly why the bind failed.
Source
Thrown at platform/cloud-web/gateway.go:95
t.caps = caps
t.mu.Unlock()
}
func (t *gatewayTransport) Start(ctx context.Context, onInbound inboundHandler) error {
t.onInbound = onInbound
runCtx, cancel := context.WithCancel(ctx)
t.cancel = cancel
mux := http.NewServeMux()
mux.HandleFunc(t.webhookPath, t.webhookHandler)
t.server = &http.Server{
Handler: mux,
ReadHeaderTimeout: 10 * time.Second,
}
ln, err := net.Listen("tcp", t.listen)
if err != nil {
cancel()
return fmt.Errorf("cloud_web: gateway listen: %w", err)
}
t.listener = ln
go func() {
slog.Info("cloud_web: gateway webhook listening", "addr", ln.Addr().String(), "path", t.webhookPath)
if err := t.server.Serve(ln); err != nil && err != http.ErrServerClosed {
slog.Error("cloud_web: gateway server error", "error", err)
}
}()
if t.registerURL != "" {
caps, err := t.register(runCtx)
if err != nil {
slog.Warn("cloud_web: gateway register failed", "error", err)
} else {
t.setCaps(caps)
}
}View on GitHub (pinned to 4000b2338a)
Solutions
- Find and stop the process holding the port (lsof -i :8099 or ss -ltnp), or kill the stale cc-connect instance.
- Change the listen value in the cloud-web platform section of config.toml to a free port (e.g. ":8100").
- If binding a privileged port, run as root, use CAP_NET_BIND_SERVICE, or put a reverse proxy in front.
- Verify the listen string syntax: '[host]:port', e.g. ':8099' or '127.0.0.1:8099'.
Example fix
// config.toml — before [[platform]] name = "cloud-web" listen = ":8099" # fails: address already in use // after [[platform]] name = "cloud-web" listen = ":8123" # free port
Defensive patterns
Strategy: validation
Validate before calling
// before calling Start, check the port is free
conn, err := net.Listen("tcp", ":8099")
if err != nil {
return fmt.Errorf("port :8099 unavailable: %w", err)
}
conn.Close() // close and let Start bind it Try / catch
if err := platform.Start(ctx, handler); err != nil {
var opErr *net.OpError
if errors.As(err, &opErr) && errors.Is(opErr.Err, syscall.EADDRINUSE) {
slog.Error("gateway port in use; stop the other instance or change listen", "error", err)
}
return err
} Prevention
- Reserve a dedicated, uncommon port for the gateway listen address
- Ensure only one cc-connect instance runs per host (systemd/launchd singleton)
- Validate the listen address syntax ([host]:port) before deployment
- Never bind privileged ports without the required capabilities
When it happens
Trigger: Calling Start (e.g. via cc-connect startup) when the configured listen address is already in use by another process, the port is privileged (below 1024) without permissions, the address is invalid/unresolvable, or an instance of cc-connect is already running with the same listen setting.
Common situations: Duplicate cc-connect instance from a stale systemd/launchd service; another dev server squatting on :8099; listen set to ':80' or ':443' in config.toml; Docker container networking the port twice; typo like 'localhost::8099'.
Related errors
- listen for Agy permission hooks: %w
- antigravity permission bridge: %w
- request usage endpoint: %w
- project %q preflight: %w
- project %q probe: %w
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/842cb7fb00607ea4.
Report an issue: GitHub.