{"record":{"id":"02166e2fc5a5bd77","repo":"AlexxIT/go2rtc","slug":"api-streamnotfound-02166e","errorCode":null,"errorMessage":"api.StreamNotFound","messagePattern":"api\\.StreamNotFound","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/mp4/ws.go","lineNumber":16,"sourceCode":"package mp4\n\nimport (\n\t\"errors\"\n\n\t\"github.com/AlexxIT/go2rtc/internal/api\"\n\t\"github.com/AlexxIT/go2rtc/internal/api/ws\"\n\t\"github.com/AlexxIT/go2rtc/internal/streams\"\n\t\"github.com/AlexxIT/go2rtc/pkg/core\"\n\t\"github.com/AlexxIT/go2rtc/pkg/mp4\"\n)\n\nfunc handlerWSMSE(tr *ws.Transport, msg *ws.Message) error {\n\tstream, _ := streams.GetOrPatch(tr.Request.URL.Query())\n\tif stream == nil {\n\t\treturn errors.New(api.StreamNotFound)\n\t}\n\n\tvar medias []*core.Media\n\tif codecs := msg.String(); codecs != \"\" {\n\t\tlog.Trace().Str(\"codecs\", codecs).Msgf(\"[mp4] new WS/MSE consumer\")\n\t\tmedias = mp4.ParseCodecs(codecs, true)\n\t}\n\n\tcons := mp4.NewConsumer(medias)\n\tcons.FormatName = \"mse/fmp4\"\n\tcons.WithRequest(tr.Request)\n\n\tif err := stream.AddConsumer(cons); err != nil {\n\t\tlog.Debug().Err(err).Msg(\"[mp4] add consumer\")\n\t\treturn err\n\t}\n\n\ttr.Write(&ws.Message{Type: \"mse\", Value: mp4.ContentType(cons.Codecs())})","sourceCodeStart":1,"sourceCodeEnd":34,"githubUrl":"https://github.com/AlexxIT/go2rtc/blob/c245815e75e2a5fd60b4290f12bfc04e55a984d3/internal/mp4/ws.go#L1-L34","documentation":"The MP4 WebSocket MSE handler (handlerWSMSE) resolves the target stream from the request query via streams.GetOrPatch and returns api.StreamNotFound when no stream matches. Without a stream there is no producer to negotiate MSE codecs against.","triggerScenarios":"Connecting to the WS MSE endpoint (/api/ws?src=...) with a src value that has no matching stream; requesting MSE playback before the stream is defined.","commonSituations":"Video player frontend initialized with a stale stream name after a config change, typos in src, or a race where the player starts before the stream was added via API.","solutions":["Fix the src query parameter to match an existing configured stream","Add the stream to go2rtc.yaml or via the streams API before opening the WS MSE connection","Verify config reload picked up newly added streams","Check client code for name typos/case mismatches"],"exampleFix":"// before\nws://host:1984/api/ws?src=front_door\n// after (stream defined as \"frontdoor\" in config)\nws://host:1984/api/ws?src=frontdoor","handlingStrategy":"validation","validationCode":"// JS: check stream availability before MSE playback\nconst r = await fetch(`/api/streams?src=${encodeURIComponent(name)}`)\nif (!r.ok) throw new Error(`stream ${name} does not exist`)\nconst ws = new WebSocket(`ws://host:1984/api/ws?src=${encodeURIComponent(name)}`)","typeGuard":null,"tryCatchPattern":"// JS\ntry {\n  ws.onmessage = handleMSE\n} catch (e) {\n  console.error('WS MSE failed:', e) // StreamNotFound => wrong src\n}","preventionTips":["URL-encode the src parameter","Confirm stream names after config changes","Start players only after the stream API reports the stream exists"],"tags":["mp4","mse","websocket","stream-not-found"],"backgroundTag":"stream-not-found","analyzedSha":"c245815e75e2a5fd60b4290f12bfc04e55a984d3","analyzedAt":"2026-09-07T11:47:02.965Z","contentChangedAt":"2026-09-07T11:47:02.965Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}