AlistGo/alist · warning
send timeout
Error message
send timeout
What it means
'send timeout' is returned by (*Http).WaitSend in internal/message/http.go when the message could not be handed to a receiver on the unbuffered ToSend channel within d seconds. The time.After branch of the select fires, meaning no HTTP message poller picked up the send during the wait window.
Source
Thrown at internal/message/http.go:66
return errors.New("send failed")
}
}
func (p *Http) Receive() (string, error) {
select {
case message := <-p.Received:
return message, nil
default:
return "", errors.New("receive failed")
}
}
func (p *Http) WaitSend(message Message, d int) error {
select {
case p.ToSend <- message:
return nil
case <-time.After(time.Duration(d) * time.Second):
return errors.New("send timeout")
}
}
func (p *Http) WaitReceive(d int) (string, error) {
select {
case message := <-p.Received:
return message, nil
case <-time.After(time.Duration(d) * time.Second):
return "", errors.New("receive timeout")
}
}
var HttpInstance = &Http{
Received: make(chan string),
ToSend: make(chan Message),
}
View on GitHub (pinned to 843d9dc814)
Solutions
- Increase the wait duration d to exceed the frontend's maximum poll gap
- Verify the message-polling endpoint is reachable and the client reconnects after network drops
- On timeout, decide explicitly whether to drop or persist the message; do not retry Send into the same absent consumer
- Consider a queue/broker for delivery guarantees if polling is unreliable
Example fix
// before err := message.HttpInstance.WaitSend(msg, 1) // after err := message.HttpInstance.WaitSend(msg, 30)
Defensive patterns
Strategy: retry
Validate before calling
// know your poller cadence before choosing d // d must exceed the frontend's max long-poll gap
Type guard
func isSendTimeout(err error) bool {
return err != nil && err.Error() == "send timeout"
} Try / catch
if err := message.HttpInstance.WaitSend(msg, d); isSendTimeout(err) {
// retry once after reconnect grace, then drop or persist
} Prevention
- Size the timeout above the client poll interval
- Ensure clients reconnect the poll after network drops
- Decide a drop/persist policy for timed-out messages
- Don't retry into a consumer known to be absent
When it happens
Trigger: WaitSend(msg, d) with no consumer attached to HttpInstance.ToSend for the entire d seconds; consumer blocked on a different request or disconnected; d set too small relative to the poll interval of the frontend.
Common situations: Browser tab closed or asleep so its message long-poll stops; frontend poll interval longer than the server-side wait; slow clients on bad networks failing to re-establish the poll in time.
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
AI-assisted analysis of AlistGo/alist@843d9dc814 (2026-08-15).
Data as JSON: /api/errors/209e812028f39f0f.
Report an issue: GitHub.