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

  1. Increase the wait duration d to exceed the frontend's maximum poll gap
  2. Verify the message-polling endpoint is reachable and the client reconnects after network drops
  3. On timeout, decide explicitly whether to drop or persist the message; do not retry Send into the same absent consumer
  4. 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

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

Related errors


AI-assisted analysis of AlistGo/alist@843d9dc814 (2026-08-15). Data as JSON: /api/errors/209e812028f39f0f. Report an issue: GitHub.