m1k1o/neko · error · ErrWebRTCStreamNotFound

webrtc stream not found

Error message

webrtc stream not found

What it means

ErrWebRTCStreamNotFound is a sentinel error in the neko types package indicating that a stream (video pipeline/stream source) referenced by a WebRTC peer does not exist. It is returned by estimatorReader and SetVideo when the requested stream id/selector cannot be resolved to an active stream on the server.

Source

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

package types

import (
	"errors"

	"github.com/pion/webrtc/v4"
)

var (
	ErrWebRTCDataChannelNotFound = errors.New("webrtc data channel not found")
	ErrWebRTCConnectionNotFound  = errors.New("webrtc connection not found")
	ErrWebRTCStreamNotFound      = errors.New("webrtc stream not found")
)

type ICEServer struct {
	URLs       []string `mapstructure:"urls"       json:"urls"`
	Username   string   `mapstructure:"username"   json:"username,omitempty"`
	Credential string   `mapstructure:"credential" json:"credential,omitempty"`
}

type PeerVideo struct {
	Disabled bool   `json:"disabled"`
	ID       string `json:"id"`
	Video    string `json:"video"` // TODO: Remove this, used for compatibility with old clients.
	Auto     bool   `json:"auto"`
}

type PeerVideoRequest struct {
	Disabled *bool           `json:"disabled,omitempty"`
	Selector *StreamSelector `json:"selector,omitempty"`

View on GitHub (pinned to b0f01cedea)

Solutions

  1. Verify the requested stream id/selector against the server's current stream list before calling SetVideo.
  2. Check that the server's capture pipeline (Xorg/display/device config) is running and exposing the expected stream.
  3. Refresh the client's stream list and retry with a valid id; stop using the legacy 'video' field if possible.
  4. Recreate the peer/stream if it was destroyed mid-session.
  5. Inspect server logs for capture-pipeline startup errors that leave no streams registered.

Example fix

// before
peer.SetVideo(types.PeerVideoRequest{Selector: &sel}) // ErrWebRTCStreamNotFound for stale id
// after
if !streams.Exists(sel.ID) {
    sel.ID = defaultStreamID // refresh from server's stream list
}
peer.SetVideo(types.PeerVideoRequest{Selector: &sel})
Defensive patterns

Strategy: validation

Validate before calling

// resolve the stream selector against live streams first
if !streamRegistry.Has(selector.ID) {
    return fmt.Errorf("stream %q not available", selector.ID)
}

Type guard

func StreamValid(sel types.StreamSelector, known []types.StreamSelector) bool {
    for _, k := range known {
        if k.ID == sel.ID { return true }
    }
    return false
}

Try / catch

if err := peer.SetVideo(req); err != nil {
    if errors.Is(err, types.ErrWebRTCStreamNotFound) {
        // refresh stream list and retry with a valid id
        return
    }
    return err
}

Prevention

When it happens

Trigger: SetVideo(PeerVideoRequest) with a stream selector/video id that has no matching active stream; estimatorReader reading statistics for a stream that already closed; requesting video before the capture pipeline started.

Common situations: Client UI cached a stale list of streams; the host stopped/shut down the stream while viewers tried to switch; typos or outdated IDs in PeerVideoRequest.Video (legacy compatibility field); config choosing a video pipeline/device that isn't present (e.g. headless server without X/display).

Related errors


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