henrygd/beszel · error

failed to send request: %w

Error message

failed to send request: %w

What it means

SendRequest registers a pending request and then writes the CBOR-encoded HubRequest over the WebSocket via sendMessage. If the write fails, the pending request is cancelled and this wrapped error is returned, so the caller never gets a response channel result.

Source

Thrown at internal/hub/ws/request_manager.go:79

		Context:    reqCtx,
		Cancel:     cancel,
		CreatedAt:  time.Now(),
	}

	rm.Lock()
	rm.pendingReqs[reqID] = req
	rm.Unlock()

	hubReq := common.HubRequest[any]{
		Id:     (*uint32)(&reqID),
		Action: action,
		Data:   data,
	}

	// Send the request
	if err := rm.sendMessage(hubReq); err != nil {
		rm.cancelRequest(reqID)
		return nil, fmt.Errorf("failed to send request: %w", err)
	}

	// Start cleanup watcher for timeout/cancellation
	go rm.cleanupRequest(req)

	return req, nil
}

// sendMessage encodes and sends a message over WebSocket
func (rm *RequestManager) sendMessage(data any) error {
	if rm.conn == nil {
		return gws.ErrConnClosed
	}

	bytes, err := cbor.Marshal(data)
	if err != nil {
		return fmt.Errorf("failed to marshal request: %w", err)
	}

View on GitHub (pinned to b38fb7dafa)

Solutions

  1. Check rm.IsConnected/conn state before sending and reconnect if needed
  2. Retry the request after the WebSocket connection is re-established
  3. Inspect the wrapped cause (%w) — often gws.ErrConnClosed — to distinguish closed-connection from transient write errors

Example fix

// before
resp, err := rm.SendRequest(ctx, action, data)
if err != nil { return err }
// after
resp, err := rm.SendRequest(ctx, action, data)
if err != nil {
    if errors.Is(err, gws.ErrConnClosed) { reconnect(); resp, err = rm.SendRequest(ctx, action, data) }
    if err != nil { return err }
}
Defensive patterns

Strategy: retry

Validate before calling

if !rm.IsConnected() {
    return errors.New("websocket not connected; reconnect before sending")
}

Try / catch

resp, err := rm.SendRequest(ctx, action, data)
if err != nil {
    if errors.Is(err, gws.ErrConnClosed) {
        // reconnect and retry once
    }
    return fmt.Errorf("hub request failed: %w", err)
}

Prevention

When it happens

Trigger: sendMessage returns an error: connection is nil/closed (gws.ErrConnClosed), the underlying WebSocket write fails due to a dropped TCP connection, or the peer is unreachable mid-request.

Common situations: Agent disconnected or restarting when the hub sends a request; network interruption/firewall drop; hub trying to talk to an agent whose WS session already closed.

Related errors


AI-assisted analysis of henrygd/beszel@b38fb7dafa (2026-08-31). Data as JSON: /api/errors/411f7bc4a8e26e73. Report an issue: GitHub.