m1k1o/neko · warning · ErrSessionAlreadyConnected

session is already connected

Error message

session is already connected

What it means

ErrSessionAlreadyConnected is a sentinel error in the neko types package indicating that a Login/connect attempt targeted a session that already has an active (WebSocket) peer connection. The server refuses a second simultaneous connection for the same session.

Source

Thrown at server/pkg/types/session.go:12

package types

import (
	"errors"
	"net/http"
	"time"
)

var (
	ErrSessionNotFound         = errors.New("session not found")
	ErrSessionAlreadyExists    = errors.New("session already exists")
	ErrSessionAlreadyConnected = errors.New("session is already connected")
	ErrSessionLoginDisabled    = errors.New("session login disabled")
	ErrSessionLoginsLocked     = errors.New("session logins locked")
)

type Cursor struct {
	X int `json:"x"`
	Y int `json:"y"`
}

type SessionProfile struct {
	Id      string
	Token   string
	Profile MemberProfile
}

type SessionState struct {
	IsConnected bool `json:"is_connected"`
	// when the session was last connected

View on GitHub (pinned to b0f01cedea)

Solutions

  1. Disconnect the existing session (Disconnect(id) or client-side logout) before reconnecting.
  2. Wait for the old connection to be cleaned up / rely on heartbeat timeout, then retry.
  3. Use the server's merciful_reconnect setting so a reconnecting peer takes over the session.
  4. Close the duplicate client tab/connection.

Example fix

// before
_, _, err := memberManager.Login(username, password) // fails: session already connected
// after
if err := sessions.Disconnect(sessionId); err != nil {
    return err
}
_, _, err = memberManager.Login(username, password)
Defensive patterns

Strategy: retry

Validate before calling

// check the session's connection state first
if st := session.State(); st.IsConnected {
    return errors.New("session already has an active connection")
}

Try / catch

err := retry.Do(func() error {
    _, _, err := manager.Login(username, password)
    if errors.Is(err, types.ErrSessionAlreadyConnected) {
        return retry.Retriable(err) // wait for cleanup, then retry
    }
    return err
})

Prevention

When it happens

Trigger: Login called for a session whose WebSocket peer is still registered as connected; a second tab/device reusing the same session while it is still marked connected.

Common situations: Opening the same neko room in two tabs with the same session; zombie connections where the old socket hasn't been cleaned up yet after a network drop; clients that don't send a proper disconnect before reconnecting.

Related errors


AI-assisted analysis of m1k1o/neko@b0f01cedea (2026-09-01). Data as JSON: /api/errors/e4e4aac548b5e825. Report an issue: GitHub.