m1k1o/neko · error · ErrBackendRespone
error response from backend
Error message
error response from backend
What it means
ErrBackendRespone (sic) is the sentinel error signaling that the legacy proxy's backend HTTP request returned a non-success status code. It is returned by session.req (via apiReq) and wrapped with the backend's JSON message or a raw body, so callers should use errors.Is to detect backend rejection regardless of formatting. The misspelling is part of the public API and must be matched exactly.
Solutions
- Inspect the wrapped message (fmt.Errorf %s) and the backend logs to find the actual status code and cause.
- Use errors.Is(err, ErrBackendRespone) to branch on backend rejection vs other failures.
- Verify backend URL, credentials/token, and API compatibility with the running backend version.
- Add retry with backoff for transient 5xx responses in apiReq callers.
Example fix
// before
if err := s.apiReq(http.MethodGet, "/api/sessions", nil, &sessions); err != nil {
return err
}
// after
if err := s.apiReq(http.MethodGet, "/api/sessions", nil, &sessions); err != nil {
if errors.Is(err, ErrBackendRespone) {
return fmt.Errorf("backend rejected sessions fetch: %w", err)
}
return err
} Defensive patterns
Strategy: try-catch
Validate before calling
resp, err := http.Head(backendURL + "/api/stats")
if err != nil || resp.StatusCode >= 400 {
return fmt.Errorf("backend not healthy before calling apiReq: status %v", resp.StatusCode)
} Type guard
func isBackendResponseError(err error) bool {
return errors.Is(err, ErrBackendRespone)
} Try / catch
if err := s.apiReq(method, path, req, &out); err != nil {
if errors.Is(err, ErrBackendRespone) {
// backend rejected: log wrapped message, maybe re-auth
return fmt.Errorf("backend error: %w", err)
}
return err
} Prevention
- Always match with errors.Is, never string comparison on the message.
- Keep the backend URL/auth configuration validated at startup.
- Monitor backend health and alert on rising non-2xx rates.
- Pin compatible proxy/backend versions to avoid API drift.
When it happens
Trigger: Any session.apiReq call (e.g. GET /api/sessions, /api/stats, /api/room/settings from Route, or create/destroy) where the backend responds with a non-2xx status and the body parses as JSON with a 'message' field.
Common situations: Backend restarted or upgrading (502/503); wrong backend URL/port configured; auth token expired causing 401/403; rate limiting on the backend; version mismatch between proxy and backend API routes.
Related errors
AI-assisted analysis of m1k1o/neko@b0f01cedea (2026-09-01).
Data as JSON: /api/errors/8546a397d4267c39.
Report an issue: GitHub.
Appendix: source
Thrown at server/internal/http/legacy/session.go:24
"fmt"
"io"
"net/http"
"path"
"strings"
"sync"
oldTypes "github.com/m1k1o/neko/server/internal/http/legacy/types"
"github.com/m1k1o/neko/server/internal/api"
"github.com/m1k1o/neko/server/pkg/types"
"github.com/gorilla/websocket"
"github.com/rs/zerolog"
)
var (
ErrWebsocketSend = fmt.Errorf("failed to send message to websocket")
ErrBackendRespone = fmt.Errorf("error response from backend")
)
type memberStruct struct {
member *oldTypes.Member
connected bool
sent bool
}
type session struct {
r *http.Request
h *LegacyHandler
logger zerolog.Logger
serverAddr string
pathPrefix string
id, ip string
token stringView on GitHub (pinned to b0f01cedea)