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
- Send a fresh signal/request (full renegotiation) instead of signal/restart when no peer exists
- Reconnect the websocket + WebRTC session entirely if the peer is gone
- Ensure the client only issues restart after a successful prior offer/answer exchange
- 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
- Only send restart after a completed offer/answer exchange
- Fall back to signal/request when peer state is gone
- Track peer lifetime client-side and reset state on disconnect
- Avoid double restarts by debouncing restart triggers
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
- receiver session ID not found
- not allowed to watch
- webrtc data channel not found
- webrtc connection not found
- webrtc stream not found
AI-assisted analysis of m1k1o/neko@b0f01cedea (2026-09-01).
Data as JSON: /api/errors/b1d778dbc2d0769b.
Report an issue: GitHub.