{"record":{"id":"272cc5cb348c1cc2","repo":"AlexxIT/go2rtc","slug":"webrtc-can-t-get-track-272cc5","errorCode":null,"errorMessage":"webrtc: can't get track","messagePattern":"webrtc: can't get track","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/webrtc/consumer.go","lineNumber":37,"sourceCode":"\n\tfor _, sender := range c.Senders {\n\t\tif sender.Codec == codec {\n\t\t\tsender.Bind(track)\n\t\t\treturn nil\n\t\t}\n\t}\n\n\tswitch c.Mode {\n\tcase core.ModePassiveConsumer: // video/audio for browser\n\tcase core.ModeActiveProducer: // go2rtc as WebRTC client (backchannel)\n\tcase core.ModePassiveProducer: // WebRTC/WHIP\n\tdefault:\n\t\tpanic(core.Caller())\n\t}\n\n\tlocalTrack := c.GetSenderTrack(media.ID)\n\tif localTrack == nil {\n\t\treturn errors.New(\"webrtc: can't get track\")\n\t}\n\n\tpayloadType := codec.PayloadType\n\n\tsender := core.NewSender(media, codec)\n\tsender.Handler = func(packet *rtp.Packet) {\n\t\tc.Send += packet.MarshalSize()\n\t\t//important to send with remote PayloadType\n\t\t_ = localTrack.WriteRTP(payloadType, packet)\n\t}\n\n\tswitch track.Codec.Name {\n\tcase core.CodecH264:\n\t\tsender.Handler = h264.RTPPay(1200, sender.Handler)\n\t\tif track.Codec.IsRTP() {\n\t\t\tsender.Handler = h264.RTPDepay(track.Codec, sender.Handler)\n\t\t} else {\n\t\t\tsender.Handler = h264.RepairAVCC(track.Codec, sender.Handler)","sourceCodeStart":19,"sourceCodeEnd":55,"githubUrl":"https://github.com/AlexxIT/go2rtc/blob/c245815e75e2a5fd60b4290f12bfc04e55a984d3/pkg/webrtc/consumer.go#L19-L55","documentation":"pkg/webrtc AddTrack sets up an outgoing RTP sender for a media/codec pair. After mapping the media kind to a track type, it asks the underlying PeerConnection for the local sender track by media ID; if the lookup returns nil the track was never registered or the media ID is invalid, so AddTrack aborts. This indicates an internal inconsistency: you are adding a track that does not exist on the connection.","triggerScenarios":"Calling webrtc Consumer AddTrack with a media whose ID was never negotiated/added on the local PeerConnection — e.g. reusing a Media object from another connection or calling AddTrack before the connection published that track, or hitting the panic branch's unexpected media kind path partially applied.","commonSituations":"Custom server code wiring medias from a stream into a WebRTC consumer where media IDs were regenerated; adding a track after the connection was closed/replaced; forwarding an audio/video media the PeerConnection never had a transceiver for.","solutions":["Ensure the media was actually added/published on the same Consumer/PeerConnection before AddTrack — use IDs the connection itself issued","Verify you are not reusing Media objects across different WebRTC sessions","Add a nil check on the media ID and log it before AddTrack to catch stale references","Update the library — this can indicate an internal invariant violation on unexpected media kinds"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"if media == nil || media.ID == \"\" {\n    return errors.New(\"media or media ID missing before AddTrack\")\n}","typeGuard":null,"tryCatchPattern":"if err := consumer.AddTrack(media, codec); err != nil {\n    if strings.Contains(err.Error(), \"can't get track\") {\n        // re-create or renegotiate the connection, don't retry blindly\n    }\n    return err\n}","preventionTips":["Only pass Media objects/IDs issued by the same WebRTC session","Never reuse media across connections; re-add media after reconnects"],"tags":["webrtc","rtp","track","internal"],"backgroundTag":"internal-invariant-violation","analyzedSha":"c245815e75e2a5fd60b4290f12bfc04e55a984d3","analyzedAt":"2026-09-07T11:47:02.965Z","contentChangedAt":"2026-09-07T11:47:02.965Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}