m1k1o/neko · error

webRTC peer does not exist

Error message

webRTC peer does not exist

What it means

signalRestart asks the existing WebRTC peer to create a new offer (ICE restart). It fetches the peer via session.GetWebRTCPeer(); when no peer has been created for this session yet, it errors with 'webRTC peer does not exist'. Restarting implies a prior negotiation, so calling it before that state exists is invalid.

Source

Thrown at server/internal/websocket/handler/signal.go:80

	}

	session.Send(
		event.SIGNAL_PROVIDE,
		message.SignalProvide{
			SDP:        offer.SDP,
			ICEServers: h.webrtc.ICEServers(),

			Video: peer.Video(),
			Audio: peer.Audio(),
		})

	return nil
}

func (h *MessageHandlerCtx) signalRestart(session types.Session) error {
	peer := session.GetWebRTCPeer()
	if peer == nil {
		return errors.New("webRTC peer does not exist")
	}

	offer, err := peer.CreateOffer(true)
	if err != nil {
		return err
	}

	// TODO: Use offer event instead.
	session.Send(
		event.SIGNAL_RESTART,
		message.SignalDescription{
			SDP: offer.SDP,
		})

	return nil
}

func (h *MessageHandlerCtx) signalOffer(session types.Session, payload *message.SignalDescription) error {

View on GitHub (pinned to b0f01cedea)

Solutions

  1. Send a fresh signal/request (full renegotiation) instead of signal/restart when no peer exists
  2. Reconnect the websocket + WebRTC session entirely if the peer is gone
  3. Ensure the client only issues restart after a successful prior offer/answer exchange
  4. Handle this server response by falling back to creating a new peer

Example fix

// before
ws.send({event: 'signal/restart'})
// after
if (peerEstablished) ws.send({event: 'signal/restart'})
else ws.send({event: 'signal/request'})
Defensive patterns

Strategy: fallback

Validate before calling

if session.GetWebRTCPeer() == nil {
  // peer missing: use signal/request instead of signal/restart
}

Type guard

func hasPeer(s types.Session) bool { return s.GetWebRTCPeer() != nil }

Try / catch

err := handler.SignalRestart(session)
if err != nil && strings.Contains(err.Error(), "webRTC peer does not exist") {
  // fall back to full renegotiation via signal/request
}

Prevention

When it happens

Trigger: Client sends a signal/restart message for a session whose peer was never created (signal/request was never answered), or whose peer was destroyed on disconnect/timeout.

Common situations: Web client reconnect logic firing 'restart' after the peer was torn down; network blip where the client restarts ICE but the server already closed the peer; duplicate restart after a failed negotiation.

Related errors


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