m1k1o/neko · warning
session not found
Error message
session not found
What it means
This error is returned by LegacyHandler.ban when a ban request references a sessionId that is not present in the handler's in-memory sessionIPs map. The legacy handler only records session-to-IP mappings when a session registers locally, so banning an unknown, already-disconnected, or never-seen session id yields this error. It is a client-side lookup failure within the proxy, not a backend failure.
Source
Thrown at server/internal/http/legacy/handler.go:433
return utils.HttpInternalServerError().WithInternalErr(err)
}
// copy the body to the response writer
_, err = io.Copy(w, body)
return err
})
r.Get("/health", func(w http.ResponseWriter, r *http.Request) error {
_, err := w.Write([]byte("true"))
return err
})
}
func (h *LegacyHandler) ban(sessionId string) error {
// find session by id
ip, ok := h.sessionIPs[sessionId]
if !ok {
return fmt.Errorf("session not found")
}
h.bannedIPs[ip] = struct{}{}
return nil
}
func (h *LegacyHandler) isBanned(r *http.Request) bool {
ip := getIp(r)
_, ok := h.bannedIPs[ip]
return ok
}
func getIp(r *http.Request) string {
ip, _, err := net.SplitHostPort(r.RemoteAddr)
if err != nil {
if e, ok := err.(*net.AddrError); ok && e.Err == "missing port in address" {
return r.RemoteAddr
}View on GitHub (pinned to b0f01cedea)
Solutions
- Verify the sessionId exists before banning by checking the sessions list (GET /api/sessions via apiReq).
- Deploy sticky routing or a shared session registry so the ban reaches the node owning the session.
- Handle the error gracefully in wsToBackend: log and skip instead of failing the moderation flow.
- If restarts lose mappings, persist sessionIPs or re-derive IP from the backend API instead of local memory.
Example fix
// before
ip, ok := h.sessionIPs[sessionId]
if !ok {
return fmt.Errorf("session not found")
}
// after
ip, ok := h.sessionIPs[sessionId]
if !ok {
log.Warn().Str("sessionId", sessionId).Msg("ban skipped: session not found on this node")
return nil // or a typed ErrSessionNotFound
} Defensive patterns
Strategy: validation
Validate before calling
if _, ok := handler.sessionIPs[sessionId]; !ok {
return fmt.Errorf("cannot ban %q: session not registered on this node", sessionId)
} Type guard
func sessionKnown(h *LegacyHandler, sessionId string) bool {
_, ok := h.sessionIPs[sessionId]
return ok
} Try / catch
if err := h.ban(id); err != nil {
if err.Error() == "session not found" {
log.Warn().Str("sessionId", id).Msg("ban skipped: session not on this node")
return nil
}
return err
} Prevention
- Check session existence via /api/sessions before issuing a ban.
- Design ban handling to be idempotent across nodes (shared session store).
- Treat 'session not found' as a no-op in moderation flows, not a failure.
- Re-derive the client IP from the backend API when the local map misses.
When it happens
Trigger: Calling LegacyHandler.ban(sessionId) with an id never registered in h.sessionIPs — e.g. wsToBackend receives a moderation/ban event (wstobackend.go:339) for a session that was created on a different node, already destroyed, or whose mapping was lost on restart.
Common situations: Multi-instance deployments where the ban event arrives at a node that does not own the session; banning a user right after they disconnect; stale session ids cached in admin UIs; server restart wiping the in-memory map while clients still reference old ids.
Related errors
- cannot select user in multiuser mode
- cannot select user in noauth mode
- no authentication provided
- session token already exists
- receiver session ID not found
AI-assisted analysis of m1k1o/neko@b0f01cedea (2026-09-01).
Data as JSON: /api/errors/35b32494fe9c5aa0.
Report an issue: GitHub.