{"record":{"id":"e546004f1cc444ff","repo":"AlexxIT/go2rtc","slug":"start-from-conn-state","errorCode":null,"errorMessage":"start from CONN state","messagePattern":"start from CONN state","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/rtsp/producer.go","lineNumber":64,"sourceCode":"\ttrack := core.NewReceiver(media, codec)\n\ttrack.ID = channel\n\tc.Receivers = append(c.Receivers, track)\n\n\treturn track, nil\n}\n\nfunc (c *Conn) Start() (err error) {\n\tcore.Assert(c.mode == core.ModeActiveProducer || c.mode == core.ModePassiveProducer)\n\n\tfor {\n\t\tok := false\n\n\t\tc.stateMu.Lock()\n\t\tswitch c.state {\n\t\tcase StateNone:\n\t\t\terr = nil\n\t\tcase StateConn:\n\t\t\terr = errors.New(\"start from CONN state\")\n\t\tcase StateSetup:\n\t\t\tswitch c.mode {\n\t\t\tcase core.ModeActiveProducer:\n\t\t\t\terr = c.Play()\n\t\t\tcase core.ModePassiveProducer:\n\t\t\t\terr = nil\n\t\t\tdefault:\n\t\t\t\terr = errors.New(\"start from wrong mode: \" + c.mode.String())\n\t\t\t}\n\n\t\t\tif err == nil {\n\t\t\t\tc.state = StatePlay\n\t\t\t\tok = true\n\t\t\t}\n\t\t}\n\t\tc.stateMu.Unlock()\n\n\t\tif !ok {","sourceCodeStart":46,"sourceCodeEnd":82,"githubUrl":"https://github.com/AlexxIT/go2rtc/blob/c245815e75e2a5fd60b4290f12bfc04e55a984d3/pkg/rtsp/producer.go#L46-L82","documentation":"Conn.Start() drives the state machine and refuses to start while the connection is stuck in StateConn (connected/authed but no media has been SET UP). Start expects either StateNone (nothing to do) or StateSetup (tracks prepared, ready to PLAY). Reaching StateConn means tracks were never added via GetTrack/SetupMedia, so there is nothing to play and Start is called at the wrong point in the lifecycle.","triggerScenarios":"Calling Start() after Dial/Options/Describe succeeded but before any GetTrack(media, codec) call put the Conn into StateSetup; the state machine hits case StateConn and returns this error.","commonSituations":"Application error handling skipped the GetTrack step (e.g. no matching codecs in DESCRIBE so GetTrack was never called); calling Start immediately after dialing in custom code; race where another goroutine reset the state; producer code paths that skipped track setup because SDP offered no supported codecs.","solutions":["Ensure GetTrack(media, codec) is called for at least one track before Start(), so the state moves from StateConn to StateSetup.","Check the DESCRIBE SDP: if no codec matched your consumer, GetTrack was never invoked — add or negotiate a supported codec.","Verify call order: Dial -> Options/Describe -> GetTrack(s) -> Start.","Inspect for concurrent goroutines racing on the Conn and resetting c.state."],"exampleFix":"// before\nconn, _ := rtsp.Dial(url)\nconn.Options()\nconn.Describe()\nerr := conn.Start() // state == StateConn -> error\n// after\nconn, _ := rtsp.Dial(url)\nconn.Options()\nconn.Describe()\nfor _, media := range conn.Medias {\n    if _, err := conn.GetTrack(media, media.Codecs[0]); err != nil {\n        return err\n    }\n}\nerr := conn.Start() // state == StateSetup -> PLAY","handlingStrategy":"validation","validationCode":"if conn.State() == StateConn {\n    return errors.New(\"call GetTrack before Start: no tracks set up\")\n}","typeGuard":null,"tryCatchPattern":"if err := conn.Start(); err != nil {\n    if strings.Contains(err.Error(), \"start from CONN state\") {\n        // recover: run track setup (GetTrack) then retry Start\n    }\n}","preventionTips":["Always follow the lifecycle: Dial -> Describe -> GetTrack(s) -> Start.","Guard Start behind a helper that performs track setup if state is StateConn.","Log c.state before Start in debug builds to catch ordering bugs early.","Handle the case where DESCRIBE yields no supported codecs — skip Start instead of calling it trackless."],"tags":["rtsp","invalid-state","state-machine","lifecycle"],"backgroundTag":"invalid-state-transition","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"}